Skip to content

Commit

Permalink
Merge pull request #265 from romancardenas/master
Browse files Browse the repository at this point in the history
Add `riscv` section for RISC-V targets
  • Loading branch information
burrbull authored Jul 21, 2024
2 parents 8194739 + ddc3d99 commit f4376aa
Show file tree
Hide file tree
Showing 20 changed files with 827 additions and 0 deletions.
2 changes: 2 additions & 0 deletions svd-encoder/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- Add `riscv` element for configuration parameters related to RISC-V targets.
You must use the `unstable-riscv` feature to enable this exeperimental element.
- Bump MSRV to 1.65.0

## [v0.14.3] - 2023-11-15
Expand Down
3 changes: 3 additions & 0 deletions svd-encoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ rust-version = "1.65.0"
version = "0.14.4"
readme = "README.md"

[features]
unstable-riscv = ["svd-rs/unstable-riscv"]

[dependencies]
convert_case = "0.6.0"
svd-rs = { version = "0.14.7", path = "../svd-rs" }
Expand Down
6 changes: 6 additions & 0 deletions svd-encoder/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ impl Encode for Device {
elem.children.push(new_node("licenseText", v.clone()));
}

#[cfg(feature = "unstable-riscv")]
if let Some(v) = &self.riscv {
elem.children
.push(XMLNode::Element(v.encode_with_config(config)?));
}

if let Some(v) = &self.cpu {
elem.children
.push(XMLNode::Element(v.encode_with_config(config)?));
Expand Down
2 changes: 2 additions & 0 deletions svd-encoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,7 @@ mod readaction;
mod register;
mod registercluster;
mod registerproperties;
#[cfg(feature = "unstable-riscv")]
mod riscv;
mod usage;
mod writeconstraint;
70 changes: 70 additions & 0 deletions svd-encoder/src/riscv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use super::{new_node, Config, Element, Encode, EncodeError, XMLNode};
use crate::svd::riscv::{Hart, Priority, Riscv};

impl Encode for Riscv {
type Error = EncodeError;

fn encode_with_config(&self, config: &Config) -> Result<Element, EncodeError> {
let mut elem = Element::new("riscv");

if !self.core_interrupts.is_empty() {
let mut interrupts = Element::new("coreInterrupts");
for interrupt in &self.core_interrupts {
interrupts
.children
.push(interrupt.encode_node_with_config(config)?);
}
elem.children.push(XMLNode::Element(interrupts));
}
if !self.priorities.is_empty() {
let mut priorities = Element::new("priorities");
for priority in &self.priorities {
priorities
.children
.push(priority.encode_node_with_config(config)?);
}
elem.children.push(XMLNode::Element(priorities));
}
if !self.harts.is_empty() {
let mut harts = Element::new("harts");
for hart in &self.harts {
harts.children.push(hart.encode_node_with_config(config)?);
}
elem.children.push(XMLNode::Element(harts));
}

Ok(elem)
}
}

impl Encode for Priority {
type Error = EncodeError;

fn encode_with_config(&self, _config: &Config) -> Result<Element, EncodeError> {
let mut children = vec![new_node("name", self.name.clone())];
if let Some(desc) = &self.description {
children.push(new_node("description", desc.clone()));
}
children.push(new_node("value", format!("{}", self.value)));

let mut elem = Element::new("priority");
elem.children = children;
Ok(elem)
}
}

impl Encode for Hart {
type Error = EncodeError;

fn encode_with_config(&self, _config: &Config) -> Result<Element, EncodeError> {
let mut children = vec![new_node("name", self.name.clone())];
if let Some(desc) = &self.description {
children.push(new_node("description", desc.clone()));
}
children.push(new_node("value", format!("{}", self.value)));

let mut elem = Element::new("hart");
elem.children = children;
Ok(elem)
}
}
2 changes: 2 additions & 0 deletions svd-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- Add `riscv` element for configuration parameters related to RISC-V targets.
You must use the `unstable-riscv` feature to enable this exeperimental element.
- Bump MSRV to 1.65.0

## [v0.14.5] - 2024-01-03
Expand Down
1 change: 1 addition & 0 deletions svd-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ readme = "README.md"
[features]
derive-from = ["svd-rs/derive-from"]
expand = ["derive-from"]
unstable-riscv = ["svd-rs/unstable-riscv"]

[dependencies]
svd-rs = { version = "0.14.7", path = "../svd-rs" }
Expand Down
6 changes: 6 additions & 0 deletions svd-parser/src/device.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::*;
#[cfg(feature = "unstable-riscv")]
use crate::svd::riscv::Riscv;
use crate::svd::{cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties};

/// Parses a SVD file
Expand Down Expand Up @@ -31,6 +33,10 @@ impl Parse for Device {
.collect();
ps?
});
#[cfg(feature = "unstable-riscv")]
if let Some(riscv) = optional::<Riscv>("riscv", tree, config)? {
device = device.riscv(riscv);
}
if let Some(version) = tree.get_child_text_opt("version")? {
device = device.version(version)
}
Expand Down
2 changes: 2 additions & 0 deletions svd-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ mod readaction;
mod register;
mod registercluster;
mod registerproperties;
#[cfg(feature = "unstable-riscv")]
mod riscv;
mod usage;
mod writeconstraint;

Expand Down
85 changes: 85 additions & 0 deletions svd-parser/src/riscv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use super::*;
use crate::svd::riscv::{Hart, Interrupt, Priority, Riscv};

impl Parse for Riscv {
type Object = Self;
type Error = SVDErrorAt;
type Config = Config;

fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
if !tree.has_tag_name("riscv") {
return Err(SVDError::NotExpectedTag("riscv".to_string()).at(tree.id()));
}

let mut builder = Riscv::builder();

if let Some(interrupts) = tree.get_child("coreInterrupts") {
let interrupts: Result<Vec<_>, _> = interrupts
.children()
.filter(|t| t.is_element() && t.has_tag_name("interrupt"))
.map(|i| Interrupt::parse(&i, config))
.collect();
builder = builder.core_interrupts(interrupts?);
}

if let Some(priorities) = tree.get_child("priorities") {
let priorities: Result<Vec<_>, _> = priorities
.children()
.filter(|t| t.is_element() && t.has_tag_name("priority"))
.map(|i| Priority::parse(&i, config))
.collect();
builder = builder.priorities(priorities?);
};

if let Some(harts) = tree.get_child("harts") {
let harts: Result<Vec<_>, _> = harts
.children()
.filter(|t| t.is_element() && t.has_tag_name("hart"))
.map(|i| Hart::parse(&i, config))
.collect();
builder = builder.harts(harts?);
};

builder
.build(config.validate_level)
.map_err(|e| SVDError::from(e).at(tree.id()))
}
}

impl Parse for Priority {
type Object = Self;
type Error = SVDErrorAt;
type Config = Config;

fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
if !tree.has_tag_name("priority") {
return Err(SVDError::NotExpectedTag("priority".to_string()).at(tree.id()));
}

Priority::builder()
.name(tree.get_child_text("name")?)
.description(tree.get_child_text_opt("description")?)
.value(tree.get_child_u32("value")?)
.build(config.validate_level)
.map_err(|e| SVDError::from(e).at(tree.id()))
}
}

impl Parse for Hart {
type Object = Self;
type Error = SVDErrorAt;
type Config = Config;

fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
if !tree.has_tag_name("hart") {
return Err(SVDError::NotExpectedTag("hart".to_string()).at(tree.id()));
}

Hart::builder()
.name(tree.get_child_text("name")?)
.description(tree.get_child_text_opt("description")?)
.value(tree.get_child_u32("value")?)
.build(config.validate_level)
.map_err(|e| SVDError::from(e).at(tree.id()))
}
}
2 changes: 2 additions & 0 deletions svd-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

- Add `riscv` element for configuration parameters related to RISC-V targets.
You must use the `unstable-riscv` feature to enable this exeperimental element.
- Add `DataType`

## [v0.14.8] - 2024-02-13
Expand Down
1 change: 1 addition & 0 deletions svd-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ readme = "README.md"

[features]
derive-from = []
unstable-riscv = []

[dependencies]
thiserror = "1.0.31"
Expand Down
26 changes: 26 additions & 0 deletions svd-rs/src/device.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "unstable-riscv")]
use super::Riscv;
use super::{
BuildError, Cpu, Description, EmptyToNone, Name, Peripheral, RegisterProperties, SvdError,
ValidateLevel,
Expand Down Expand Up @@ -105,6 +107,14 @@ pub struct Device {
/// Specify the compliant CMSIS-SVD schema version
#[cfg_attr(feature = "serde", serde(skip, default = "default_schema_version"))]
pub schema_version: String,

/// Describe the processor included in the device
#[cfg_attr(
feature = "serde",
serde(default, skip_serializing_if = "Option::is_none")
)]
#[cfg(feature = "unstable-riscv")]
pub riscv: Option<Riscv>,
}

fn default_xmlns_xs() -> String {
Expand All @@ -130,6 +140,8 @@ pub struct DeviceBuilder {
version: Option<String>,
description: Option<String>,
license_text: Option<String>,
#[cfg(feature = "unstable-riscv")]
riscv: Option<Riscv>,
cpu: Option<Cpu>,
header_system_filename: Option<String>,
header_definitions_prefix: Option<String>,
Expand All @@ -152,6 +164,8 @@ impl From<Device> for DeviceBuilder {
version: Some(d.version),
description: Some(d.description),
license_text: d.license_text,
#[cfg(feature = "unstable-riscv")]
riscv: d.riscv,
cpu: d.cpu,
header_system_filename: d.header_system_filename,
header_definitions_prefix: d.header_definitions_prefix,
Expand Down Expand Up @@ -202,6 +216,12 @@ impl DeviceBuilder {
self.license_text = value;
self
}
/// Set the riscv of the device.
#[cfg(feature = "unstable-riscv")]
pub fn riscv(mut self, value: Riscv) -> Self {
self.riscv = Some(value);
self
}
/// Set the cpu of the device.
pub fn cpu(mut self, value: Option<Cpu>) -> Self {
self.cpu = value;
Expand Down Expand Up @@ -283,6 +303,8 @@ impl DeviceBuilder {
})
.ok_or_else(|| BuildError::Uninitialized("description".to_string()))?,
license_text: self.license_text,
#[cfg(feature = "unstable-riscv")]
riscv: self.riscv,
cpu: self.cpu,
header_system_filename: self.header_system_filename,
header_definitions_prefix: self.header_definitions_prefix,
Expand Down Expand Up @@ -341,6 +363,10 @@ impl Device {
if builder.license_text.is_some() {
self.license_text = builder.license_text.empty_to_none();
}
#[cfg(feature = "unstable-riscv")]
if builder.riscv.is_some() {
self.riscv = builder.riscv;
}
if builder.cpu.is_some() {
self.cpu = builder.cpu;
}
Expand Down
6 changes: 6 additions & 0 deletions svd-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ pub use self::protection::Protection;
pub mod datatype;
pub use self::datatype::DataType;

/// Custom objects for the RISC-V ecosystem
#[cfg(feature = "unstable-riscv")]
pub mod riscv;
#[cfg(feature = "unstable-riscv")]
pub use self::riscv::Riscv;

/// Level of validation
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ValidateLevel {
Expand Down
Loading

0 comments on commit f4376aa

Please sign in to comment.