From 0f73e457b86edb3aee0823e13739ea350e519c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Sat, 29 Jun 2024 21:04:29 +0200 Subject: [PATCH 1/5] riscv section --- svd-encoder/CHANGELOG.md | 1 + svd-encoder/src/lib.rs | 1 + svd-encoder/src/riscv.rs | 79 +++++++++++ svd-parser/CHANGELOG.md | 1 + svd-parser/src/lib.rs | 1 + svd-parser/src/riscv.rs | 88 +++++++++++++ svd-rs/CHANGELOG.md | 1 + svd-rs/src/lib.rs | 3 + svd-rs/src/riscv.rs | 198 ++++++++++++++++++++++++++++ svd-rs/src/riscv/hart.rs | 114 ++++++++++++++++ svd-rs/src/riscv/priority.rs | 114 ++++++++++++++++ tests/src/lib.rs | 2 + tests/src/riscv.rs | 246 +++++++++++++++++++++++++++++++++++ 13 files changed, 849 insertions(+) create mode 100644 svd-encoder/src/riscv.rs create mode 100644 svd-parser/src/riscv.rs create mode 100644 svd-rs/src/riscv.rs create mode 100644 svd-rs/src/riscv/hart.rs create mode 100644 svd-rs/src/riscv/priority.rs create mode 100644 tests/src/riscv.rs diff --git a/svd-encoder/CHANGELOG.md b/svd-encoder/CHANGELOG.md index bbd90e98..00b6a214 100644 --- a/svd-encoder/CHANGELOG.md +++ b/svd-encoder/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Add `riscv` element for configuration parameters related to RISC-V targets. - Bump MSRV to 1.65.0 ## [v0.14.3] - 2023-11-15 diff --git a/svd-encoder/src/lib.rs b/svd-encoder/src/lib.rs index 7f531426..45ca07a8 100644 --- a/svd-encoder/src/lib.rs +++ b/svd-encoder/src/lib.rs @@ -103,5 +103,6 @@ mod readaction; mod register; mod registercluster; mod registerproperties; +mod riscv; mod usage; mod writeconstraint; diff --git a/svd-encoder/src/riscv.rs b/svd-encoder/src/riscv.rs new file mode 100644 index 00000000..37042f58 --- /dev/null +++ b/svd-encoder/src/riscv.rs @@ -0,0 +1,79 @@ +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 { + let mut elem = Element::new("riscv"); + + if let Some(clic) = &self.clic { + elem.children.push(new_node("clic", clic.clone())); + } + if let Some(clint) = &self.clint { + elem.children.push(new_node("clint", clint.clone())); + } + if let Some(plic) = &self.plic { + elem.children.push(new_node("plic", plic.clone())); + } + 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 { + 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 { + 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) + } +} diff --git a/svd-parser/CHANGELOG.md b/svd-parser/CHANGELOG.md index 219cad51..62063e72 100644 --- a/svd-parser/CHANGELOG.md +++ b/svd-parser/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Add `riscv` element for configuration parameters related to RISC-V targets. - Bump MSRV to 1.65.0 ## [v0.14.5] - 2024-01-03 diff --git a/svd-parser/src/lib.rs b/svd-parser/src/lib.rs index b3d22c6d..4c3c09d7 100644 --- a/svd-parser/src/lib.rs +++ b/svd-parser/src/lib.rs @@ -211,6 +211,7 @@ mod readaction; mod register; mod registercluster; mod registerproperties; +mod riscv; mod usage; mod writeconstraint; diff --git a/svd-parser/src/riscv.rs b/svd-parser/src/riscv.rs new file mode 100644 index 00000000..43e99fe4 --- /dev/null +++ b/svd-parser/src/riscv.rs @@ -0,0 +1,88 @@ +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 { + if !tree.has_tag_name("riscv") { + return Err(SVDError::NotExpectedTag("riscv".to_string()).at(tree.id())); + } + + let mut builder = Riscv::builder() + .clic(tree.get_child_text("clic").ok()) + .clint(tree.get_child_text("clint").ok()) + .plic(tree.get_child_text("plic").ok()); + + if let Some(interrupts) = tree.get_child("coreInterrupts") { + let interrupts: Result, _> = 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, _> = 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, _> = 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 { + 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 { + 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())) + } +} diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index fc66bfc0..73f4e36c 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Add `riscv` element for configuration parameters related to RISC-V targets. - Add `DataType` ## [v0.14.8] - 2024-02-13 diff --git a/svd-rs/src/lib.rs b/svd-rs/src/lib.rs index fe895426..381be203 100644 --- a/svd-rs/src/lib.rs +++ b/svd-rs/src/lib.rs @@ -94,6 +94,9 @@ pub use self::protection::Protection; pub mod datatype; pub use self::datatype::DataType; +/// Custom objects for the RISC-V ecosystem +pub mod riscv; + /// Level of validation #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ValidateLevel { diff --git a/svd-rs/src/riscv.rs b/svd-rs/src/riscv.rs new file mode 100644 index 00000000..b8eee6ee --- /dev/null +++ b/svd-rs/src/riscv.rs @@ -0,0 +1,198 @@ +pub use super::Interrupt; +use super::{BuildError, SvdError, ValidateLevel}; + +/// Description of HARTs in the device. +pub mod hart; +pub use hart::Hart; + +/// Description of interrupt priority levels in the device. +pub mod priority; +pub use priority::Priority; + +/// RISC-V specific descriptions. +#[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize), + serde(rename_all = "camelCase") +)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub struct Riscv { + /// Indicate the ID of the CLIC peripheral (if present). + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub clic: Option, + + /// Indicate the ID of the CLINT peripheral (if present). + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub clint: Option, + + /// Indicate the ID of the PLIC peripheral (if present). + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub plic: Option, + + /// Core interrupt enumeration values + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty") + )] + pub core_interrupts: Vec, + + /// Priority level enumeration values + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty") + )] + pub priorities: Vec, + + /// HART enumeration values + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty") + )] + pub harts: Vec, +} + +/// Builder for [`Riscv`] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct RiscvBuilder { + clic: Option, + clint: Option, + plic: Option, + core_interrupts: Option>, + priorities: Option>, + harts: Option>, +} + +impl From for RiscvBuilder { + fn from(riscv: Riscv) -> Self { + Self { + clic: riscv.clic, + clint: riscv.clint, + plic: riscv.plic, + core_interrupts: Some(riscv.core_interrupts), + priorities: Some(riscv.priorities), + harts: Some(riscv.harts), + } + } +} + +impl RiscvBuilder { + /// Set the ID of the CLIC peripheral + pub fn clic(mut self, clic: Option) -> Self { + self.clic = clic; + self + } + + /// Set the ID of the CLINT peripheral + pub fn clint(mut self, clint: Option) -> Self { + self.clint = clint; + self + } + + /// Set the ID of the PLIC peripheral + pub fn plic(mut self, plic: Option) -> Self { + self.plic = plic; + self + } + + /// Set the core interrupt enumeration values + pub fn core_interrupts(mut self, core_interrupts: Vec) -> Self { + self.core_interrupts = Some(core_interrupts); + self + } + + /// Set the priority level enumeration values + pub fn priorities(mut self, priorities: Vec) -> Self { + self.priorities = Some(priorities); + self + } + + /// Set the HART enumeration values + pub fn harts(mut self, harts: Vec) -> Self { + self.harts = Some(harts); + self + } + + /// Validate and build a [`Riscv`]. + pub fn build(self, lvl: ValidateLevel) -> Result { + let riscv = Riscv { + clic: self.clic, + clint: self.clint, + plic: self.plic, + core_interrupts: self + .core_interrupts + .ok_or_else(|| BuildError::Uninitialized("core_interrupts".to_string()))?, + priorities: self + .priorities + .ok_or_else(|| BuildError::Uninitialized("priorities".to_string()))?, + harts: self + .harts + .ok_or_else(|| BuildError::Uninitialized("harts".to_string()))?, + }; + riscv.validate(lvl)?; + Ok(riscv) + } +} + +impl Riscv { + /// Make a builder for [`Riscv`] + pub fn builder() -> RiscvBuilder { + RiscvBuilder::default() + } + + /// Modify an existing [`Riscv`] based on a [builder](RiscvBuilder). + pub fn modify_from( + &mut self, + builder: RiscvBuilder, + lvl: ValidateLevel, + ) -> Result<(), SvdError> { + if builder.clic.is_some() { + self.clic = builder.clic; + } + if builder.clint.is_some() { + self.clint = builder.clint; + } + if builder.plic.is_some() { + self.plic = builder.plic; + } + if let Some(core_interrupts) = builder.core_interrupts { + self.core_interrupts = core_interrupts; + } + if let Some(priorities) = builder.priorities { + self.priorities = priorities; + } + if let Some(harts) = builder.harts { + self.harts = harts; + } + self.validate(lvl) + } + + /// Validate the [`Riscv`]. + /// + /// # Errors + /// + /// - If any of the core interrupt enumeration values are invalid + /// - If any of the priority level enumeration values are invalid + /// - If any of the HART enumeration values are invalid + pub fn validate(&self, lvl: ValidateLevel) -> Result<(), SvdError> { + for ci in &self.core_interrupts { + ci.validate(lvl)?; + } + for p in &self.priorities { + p.validate(lvl)?; + } + for h in &self.harts { + h.validate(lvl)?; + } + Ok(()) + } +} diff --git a/svd-rs/src/riscv/hart.rs b/svd-rs/src/riscv/hart.rs new file mode 100644 index 00000000..27e7ad09 --- /dev/null +++ b/svd-rs/src/riscv/hart.rs @@ -0,0 +1,114 @@ +use crate::{BuildError, Description, Name, SvdError, ValidateLevel}; + +/// Describes a HART ID in the device +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub struct Hart { + /// The string represents the HART ID + pub name: String, + + /// The string describes the HART ID + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub description: Option, + + /// Represents the enumeration index value associated to the HART ID + pub value: u32, +} + +/// Builder for [`Hart`] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct HartBuilder { + name: Option, + description: Option, + value: Option, +} + +impl From for HartBuilder { + fn from(d: Hart) -> Self { + Self { + name: Some(d.name), + description: d.description, + value: Some(d.value), + } + } +} + +impl HartBuilder { + /// Set the name of the HART + pub fn name(mut self, value: String) -> Self { + self.name = Some(value); + self + } + /// Set the description of the HART + pub fn description(mut self, value: Option) -> Self { + self.description = value; + self + } + /// Set the value of the HART + pub fn value(mut self, value: u32) -> Self { + self.value = Some(value); + self + } + /// Validate and build a [`Hart`]. + pub fn build(self, lvl: ValidateLevel) -> Result { + let de = Hart { + name: self + .name + .ok_or_else(|| BuildError::Uninitialized("name".to_string()))?, + description: self.description, + value: self + .value + .ok_or_else(|| BuildError::Uninitialized("value".to_string()))?, + }; + de.validate(lvl)?; + Ok(de) + } +} + +impl Hart { + /// Make a builder for [`Hart`] + pub fn builder() -> HartBuilder { + HartBuilder::default() + } + /// Modify an existing [`Hart`] based on a [builder](HartBuilder). + pub fn modify_from( + &mut self, + builder: HartBuilder, + lvl: ValidateLevel, + ) -> Result<(), SvdError> { + if let Some(name) = builder.name { + self.name = name; + } + if builder.description.is_some() { + self.description = builder.description; + } + if let Some(value) = builder.value { + self.value = value; + } + self.validate(lvl) + } + /// Validate the [`Hart`]. + /// + /// # Notes + /// + /// This doesn't do anything. + pub fn validate(&self, _lvl: ValidateLevel) -> Result<(), SvdError> { + Ok(()) + } +} + +impl Name for Hart { + fn name(&self) -> &str { + &self.name + } +} + +impl Description for Hart { + fn description(&self) -> Option<&str> { + self.description.as_deref() + } +} diff --git a/svd-rs/src/riscv/priority.rs b/svd-rs/src/riscv/priority.rs new file mode 100644 index 00000000..80ab85ac --- /dev/null +++ b/svd-rs/src/riscv/priority.rs @@ -0,0 +1,114 @@ +use crate::{BuildError, Description, Name, SvdError, ValidateLevel}; + +/// Describes a priority level in the device +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[derive(Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub struct Priority { + /// The string represents the priority level + pub name: String, + + /// The string describes the priority level + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + pub description: Option, + + /// Represents the enumeration index value associated to the priority level + pub value: u32, +} + +/// Builder for [`Priority`] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct PriorityBuilder { + name: Option, + description: Option, + value: Option, +} + +impl From for PriorityBuilder { + fn from(d: Priority) -> Self { + Self { + name: Some(d.name), + description: d.description, + value: Some(d.value), + } + } +} + +impl PriorityBuilder { + /// Set the name of the priority level + pub fn name(mut self, value: String) -> Self { + self.name = Some(value); + self + } + /// Set the description of the priority level + pub fn description(mut self, value: Option) -> Self { + self.description = value; + self + } + /// Set the value of the priority level + pub fn value(mut self, value: u32) -> Self { + self.value = Some(value); + self + } + /// Validate and build a [`Priority`]. + pub fn build(self, lvl: ValidateLevel) -> Result { + let de = Priority { + name: self + .name + .ok_or_else(|| BuildError::Uninitialized("name".to_string()))?, + description: self.description, + value: self + .value + .ok_or_else(|| BuildError::Uninitialized("value".to_string()))?, + }; + de.validate(lvl)?; + Ok(de) + } +} + +impl Priority { + /// Make a builder for [`Priority`] + pub fn builder() -> PriorityBuilder { + PriorityBuilder::default() + } + /// Modify an existing [`Priority`] based on a [builder](PriorityBuilder). + pub fn modify_from( + &mut self, + builder: PriorityBuilder, + lvl: ValidateLevel, + ) -> Result<(), SvdError> { + if let Some(name) = builder.name { + self.name = name; + } + if builder.description.is_some() { + self.description = builder.description; + } + if let Some(value) = builder.value { + self.value = value; + } + self.validate(lvl) + } + /// Validate the [`Priority`]. + /// + /// # Notes + /// + /// This doesn't do anything. + pub fn validate(&self, _lvl: ValidateLevel) -> Result<(), SvdError> { + Ok(()) + } +} + +impl Name for Priority { + fn name(&self) -> &str { + &self.name + } +} + +impl Description for Priority { + fn description(&self) -> Option<&str> { + self.description.as_deref() + } +} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 68f4a9dd..c23fd2d0 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -61,3 +61,5 @@ mod register; //mod registerproperties; mod usage; mod writeconstraint; + +mod riscv; diff --git a/tests/src/riscv.rs b/tests/src/riscv.rs new file mode 100644 index 00000000..39796e9f --- /dev/null +++ b/tests/src/riscv.rs @@ -0,0 +1,246 @@ +use std::vec; + +use super::run_test; +use crate::svd::{ + riscv::{Hart, Priority, Riscv}, + Interrupt, ValidateLevel, +}; + +#[test] +fn decode_encode() { + let interrupts = vec![ + Interrupt::builder() + .name("MachineSoft".to_string()) + .description(Some("Machine Software Interrupt".to_string())) + .value(3) + .build(ValidateLevel::Strict) + .unwrap(), + Interrupt::builder() + .name("MachineTimer".to_string()) + .description(Some("Machine Timer Interrupt".to_string())) + .value(7) + .build(ValidateLevel::Strict) + .unwrap(), + Interrupt::builder() + .name("MachineExternal".to_string()) + .description(Some("Machine External Interrupt".to_string())) + .value(11) + .build(ValidateLevel::Strict) + .unwrap(), + ]; + + let priorities = vec![ + Priority::builder() + .name("P0".to_string()) + .description(Some("Priority level 0".to_string())) + .value(0) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P1".to_string()) + .description(Some("Priority level 1".to_string())) + .value(1) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P2".to_string()) + .description(Some("Priority level 2".to_string())) + .value(2) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P3".to_string()) + .description(Some("Priority level 3".to_string())) + .value(3) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P4".to_string()) + .description(Some("Priority level 4".to_string())) + .value(4) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P5".to_string()) + .description(Some("Priority level 5".to_string())) + .value(5) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P6".to_string()) + .description(Some("Priority level 6".to_string())) + .value(6) + .build(ValidateLevel::Strict) + .unwrap(), + Priority::builder() + .name("P7".to_string()) + .description(Some("Priority level 7".to_string())) + .value(7) + .build(ValidateLevel::Strict) + .unwrap(), + ]; + + let harts = vec![Hart::builder() + .name("H0".to_string()) + .description(Some("Hart 0".to_string())) + .value(0) + .build(ValidateLevel::Strict) + .unwrap()]; + + let tests = vec![( + Riscv::builder() + .clint(Some("CLINT".to_string())) + .plic(Some("PLIC".to_string())) + .core_interrupts(interrupts) + .priorities(priorities) + .harts(harts) + .build(ValidateLevel::Strict) + .unwrap(), + " + + CLINT + PLIC + + + MachineSoft + Machine Software Interrupt + 3 + + + MachineTimer + Machine Timer Interrupt + 7 + + + MachineExternal + Machine External Interrupt + 11 + + + + + P0 + Priority level 0 + 0 + + + P1 + Priority level 1 + 1 + + + P2 + Priority level 2 + 2 + + + P3 + Priority level 3 + 3 + + + P4 + Priority level 4 + 4 + + + P5 + Priority level 5 + 5 + + + P6 + Priority level 6 + 6 + + + P7 + Priority level 7 + 7 + + + + + H0 + Hart 0 + 0 + + + + ", + " + + CLINT + PLIC + + + MachineSoft + Machine Software Interrupt + 3 + + + MachineTimer + Machine Timer Interrupt + 7 + + + MachineExternal + Machine External Interrupt + 11 + + + + + P0 + Priority level 0 + 0 + + + P1 + Priority level 1 + 1 + + + P2 + Priority level 2 + 2 + + + P3 + Priority level 3 + 3 + + + P4 + Priority level 4 + 4 + + + P5 + Priority level 5 + 5 + + + P6 + Priority level 6 + 6 + + + P7 + Priority level 7 + 7 + + + + + H0 + Hart 0 + 0 + + + + ", + )]; + + run_test::(&tests[..], None, None); +} From a6865468255343dab80598138c6166024c259c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Sun, 30 Jun 2024 00:57:27 +0200 Subject: [PATCH 2/5] Add riscv to device --- svd-encoder/src/device.rs | 6 ++++++ svd-parser/src/device.rs | 5 ++++- svd-rs/src/device.rs | 22 ++++++++++++++++++++-- svd-rs/src/lib.rs | 1 + 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/svd-encoder/src/device.rs b/svd-encoder/src/device.rs index 378e6536..6a2071f4 100644 --- a/svd-encoder/src/device.rs +++ b/svd-encoder/src/device.rs @@ -34,6 +34,12 @@ impl Encode for Device { elem.children.push(new_node("licenseText", v.clone())); } + // TODO not sure if this is the correct position + 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)?)); diff --git a/svd-parser/src/device.rs b/svd-parser/src/device.rs index 32ec8d07..84df6218 100644 --- a/svd-parser/src/device.rs +++ b/svd-parser/src/device.rs @@ -1,5 +1,7 @@ use super::*; -use crate::svd::{cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties}; +use crate::svd::{ + cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties, riscv::Riscv, +}; /// Parses a SVD file impl Parse for Device { @@ -18,6 +20,7 @@ impl Parse for Device { .name(tree.get_child_text("name")?) .series(tree.get_child_text_opt("series")?) .license_text(tree.get_child_text_opt("licenseText")?) + .riscv(optional::("riscv", tree, config)?) .cpu(optional::("cpu", tree, config)?) .header_system_filename(tree.get_child_text_opt("headerSystemFilename")?) .header_definitions_prefix(tree.get_child_text_opt("headerDefinitionsPrefix")?) diff --git a/svd-rs/src/device.rs b/svd-rs/src/device.rs index aa9d4439..224383fd 100644 --- a/svd-rs/src/device.rs +++ b/svd-rs/src/device.rs @@ -1,6 +1,6 @@ use super::{ - BuildError, Cpu, Description, EmptyToNone, Name, Peripheral, RegisterProperties, SvdError, - ValidateLevel, + BuildError, Cpu, Description, EmptyToNone, Name, Peripheral, RegisterProperties, Riscv, + SvdError, ValidateLevel, }; /// Errors for [`Device::validate`] @@ -105,6 +105,13 @@ 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") + )] + pub riscv: Option, } fn default_xmlns_xs() -> String { @@ -130,6 +137,7 @@ pub struct DeviceBuilder { version: Option, description: Option, license_text: Option, + riscv: Option, cpu: Option, header_system_filename: Option, header_definitions_prefix: Option, @@ -152,6 +160,7 @@ impl From for DeviceBuilder { version: Some(d.version), description: Some(d.description), license_text: d.license_text, + riscv: d.riscv, cpu: d.cpu, header_system_filename: d.header_system_filename, header_definitions_prefix: d.header_definitions_prefix, @@ -202,6 +211,11 @@ impl DeviceBuilder { self.license_text = value; self } + /// Set the riscv of the device. + pub fn riscv(mut self, value: Option) -> Self { + self.riscv = value; + self + } /// Set the cpu of the device. pub fn cpu(mut self, value: Option) -> Self { self.cpu = value; @@ -283,6 +297,7 @@ impl DeviceBuilder { }) .ok_or_else(|| BuildError::Uninitialized("description".to_string()))?, license_text: self.license_text, + riscv: self.riscv, cpu: self.cpu, header_system_filename: self.header_system_filename, header_definitions_prefix: self.header_definitions_prefix, @@ -341,6 +356,9 @@ impl Device { if builder.license_text.is_some() { self.license_text = builder.license_text.empty_to_none(); } + if builder.riscv.is_some() { + self.riscv = builder.riscv; + } if builder.cpu.is_some() { self.cpu = builder.cpu; } diff --git a/svd-rs/src/lib.rs b/svd-rs/src/lib.rs index 381be203..d59f35c9 100644 --- a/svd-rs/src/lib.rs +++ b/svd-rs/src/lib.rs @@ -96,6 +96,7 @@ pub use self::datatype::DataType; /// Custom objects for the RISC-V ecosystem pub mod riscv; +pub use self::riscv::Riscv; /// Level of validation #[derive(Clone, Copy, Debug, PartialEq, Eq)] From 5b2de117206b48e5ca9056521b28815e75d05e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Sun, 30 Jun 2024 21:55:41 +0200 Subject: [PATCH 3/5] point to fork (temporary) --- svd-encoder/Cargo.toml | 3 ++- svd-parser/Cargo.toml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/svd-encoder/Cargo.toml b/svd-encoder/Cargo.toml index fefa7128..1eb0b5b7 100644 --- a/svd-encoder/Cargo.toml +++ b/svd-encoder/Cargo.toml @@ -13,7 +13,8 @@ readme = "README.md" [dependencies] convert_case = "0.6.0" -svd-rs = { version = "0.14.7", path = "../svd-rs" } +svd-rs = { repository = "https://github.com/romancardenas/svd.git" } # TODO use crates.io +# svd-rs = { version = "0.14.7", path = "../svd-rs" } thiserror = "1.0.31" [dependencies.xmltree] diff --git a/svd-parser/Cargo.toml b/svd-parser/Cargo.toml index b500cdd4..192110f4 100644 --- a/svd-parser/Cargo.toml +++ b/svd-parser/Cargo.toml @@ -19,7 +19,8 @@ derive-from = ["svd-rs/derive-from"] expand = ["derive-from"] [dependencies] -svd-rs = { version = "0.14.7", path = "../svd-rs" } +svd-rs = { repository = "https://github.com/romancardenas/svd.git" } # TODO use crates.io +# svd-rs = { version = "0.14.7", path = "../svd-rs" } roxmltree = "0.19" anyhow = "1.0.58" thiserror = "1.0.31" From 71b33bfa56c51932a685ac7fe91f1cbe9d009fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Mon, 1 Jul 2024 08:30:36 +0200 Subject: [PATCH 4/5] Revert "point to fork (temporary)" This reverts commit 5b2de117206b48e5ca9056521b28815e75d05e5d. --- svd-encoder/Cargo.toml | 3 +-- svd-parser/Cargo.toml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/svd-encoder/Cargo.toml b/svd-encoder/Cargo.toml index 1eb0b5b7..fefa7128 100644 --- a/svd-encoder/Cargo.toml +++ b/svd-encoder/Cargo.toml @@ -13,8 +13,7 @@ readme = "README.md" [dependencies] convert_case = "0.6.0" -svd-rs = { repository = "https://github.com/romancardenas/svd.git" } # TODO use crates.io -# svd-rs = { version = "0.14.7", path = "../svd-rs" } +svd-rs = { version = "0.14.7", path = "../svd-rs" } thiserror = "1.0.31" [dependencies.xmltree] diff --git a/svd-parser/Cargo.toml b/svd-parser/Cargo.toml index 192110f4..b500cdd4 100644 --- a/svd-parser/Cargo.toml +++ b/svd-parser/Cargo.toml @@ -19,8 +19,7 @@ derive-from = ["svd-rs/derive-from"] expand = ["derive-from"] [dependencies] -svd-rs = { repository = "https://github.com/romancardenas/svd.git" } # TODO use crates.io -# svd-rs = { version = "0.14.7", path = "../svd-rs" } +svd-rs = { version = "0.14.7", path = "../svd-rs" } roxmltree = "0.19" anyhow = "1.0.58" thiserror = "1.0.31" From ddc3d99e9aea74930fb4ae3e401b984a09c7d398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Wed, 3 Jul 2024 14:42:08 +0200 Subject: [PATCH 5/5] unstable-riscv feature --- svd-encoder/CHANGELOG.md | 1 + svd-encoder/Cargo.toml | 3 +++ svd-encoder/src/device.rs | 2 +- svd-encoder/src/lib.rs | 1 + svd-encoder/src/riscv.rs | 9 ------- svd-parser/CHANGELOG.md | 1 + svd-parser/Cargo.toml | 1 + svd-parser/src/device.rs | 11 +++++--- svd-parser/src/lib.rs | 1 + svd-parser/src/riscv.rs | 5 +--- svd-rs/CHANGELOG.md | 1 + svd-rs/Cargo.toml | 1 + svd-rs/src/device.rs | 16 ++++++++--- svd-rs/src/lib.rs | 2 ++ svd-rs/src/riscv.rs | 57 --------------------------------------- tests/Cargo.toml | 3 +++ tests/src/lib.rs | 1 + tests/src/riscv.rs | 8 ------ 18 files changed, 37 insertions(+), 87 deletions(-) diff --git a/svd-encoder/CHANGELOG.md b/svd-encoder/CHANGELOG.md index 00b6a214..cb7d00ec 100644 --- a/svd-encoder/CHANGELOG.md +++ b/svd-encoder/CHANGELOG.md @@ -8,6 +8,7 @@ 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 diff --git a/svd-encoder/Cargo.toml b/svd-encoder/Cargo.toml index fefa7128..cb584e58 100644 --- a/svd-encoder/Cargo.toml +++ b/svd-encoder/Cargo.toml @@ -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" } diff --git a/svd-encoder/src/device.rs b/svd-encoder/src/device.rs index 6a2071f4..8341f446 100644 --- a/svd-encoder/src/device.rs +++ b/svd-encoder/src/device.rs @@ -34,7 +34,7 @@ impl Encode for Device { elem.children.push(new_node("licenseText", v.clone())); } - // TODO not sure if this is the correct position + #[cfg(feature = "unstable-riscv")] if let Some(v) = &self.riscv { elem.children .push(XMLNode::Element(v.encode_with_config(config)?)); diff --git a/svd-encoder/src/lib.rs b/svd-encoder/src/lib.rs index 45ca07a8..88d750e3 100644 --- a/svd-encoder/src/lib.rs +++ b/svd-encoder/src/lib.rs @@ -103,6 +103,7 @@ mod readaction; mod register; mod registercluster; mod registerproperties; +#[cfg(feature = "unstable-riscv")] mod riscv; mod usage; mod writeconstraint; diff --git a/svd-encoder/src/riscv.rs b/svd-encoder/src/riscv.rs index 37042f58..dfb66f7a 100644 --- a/svd-encoder/src/riscv.rs +++ b/svd-encoder/src/riscv.rs @@ -7,15 +7,6 @@ impl Encode for Riscv { fn encode_with_config(&self, config: &Config) -> Result { let mut elem = Element::new("riscv"); - if let Some(clic) = &self.clic { - elem.children.push(new_node("clic", clic.clone())); - } - if let Some(clint) = &self.clint { - elem.children.push(new_node("clint", clint.clone())); - } - if let Some(plic) = &self.plic { - elem.children.push(new_node("plic", plic.clone())); - } if !self.core_interrupts.is_empty() { let mut interrupts = Element::new("coreInterrupts"); for interrupt in &self.core_interrupts { diff --git a/svd-parser/CHANGELOG.md b/svd-parser/CHANGELOG.md index 62063e72..a22d267c 100644 --- a/svd-parser/CHANGELOG.md +++ b/svd-parser/CHANGELOG.md @@ -8,6 +8,7 @@ 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 diff --git a/svd-parser/Cargo.toml b/svd-parser/Cargo.toml index b500cdd4..1b45a4ae 100644 --- a/svd-parser/Cargo.toml +++ b/svd-parser/Cargo.toml @@ -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" } diff --git a/svd-parser/src/device.rs b/svd-parser/src/device.rs index 84df6218..701055fc 100644 --- a/svd-parser/src/device.rs +++ b/svd-parser/src/device.rs @@ -1,7 +1,7 @@ use super::*; -use crate::svd::{ - cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties, riscv::Riscv, -}; +#[cfg(feature = "unstable-riscv")] +use crate::svd::riscv::Riscv; +use crate::svd::{cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties}; /// Parses a SVD file impl Parse for Device { @@ -20,7 +20,6 @@ impl Parse for Device { .name(tree.get_child_text("name")?) .series(tree.get_child_text_opt("series")?) .license_text(tree.get_child_text_opt("licenseText")?) - .riscv(optional::("riscv", tree, config)?) .cpu(optional::("cpu", tree, config)?) .header_system_filename(tree.get_child_text_opt("headerSystemFilename")?) .header_definitions_prefix(tree.get_child_text_opt("headerDefinitionsPrefix")?) @@ -34,6 +33,10 @@ impl Parse for Device { .collect(); ps? }); + #[cfg(feature = "unstable-riscv")] + if let Some(riscv) = optional::("riscv", tree, config)? { + device = device.riscv(riscv); + } if let Some(version) = tree.get_child_text_opt("version")? { device = device.version(version) } diff --git a/svd-parser/src/lib.rs b/svd-parser/src/lib.rs index 4c3c09d7..e3718ed6 100644 --- a/svd-parser/src/lib.rs +++ b/svd-parser/src/lib.rs @@ -211,6 +211,7 @@ mod readaction; mod register; mod registercluster; mod registerproperties; +#[cfg(feature = "unstable-riscv")] mod riscv; mod usage; mod writeconstraint; diff --git a/svd-parser/src/riscv.rs b/svd-parser/src/riscv.rs index 43e99fe4..fe744e4a 100644 --- a/svd-parser/src/riscv.rs +++ b/svd-parser/src/riscv.rs @@ -11,10 +11,7 @@ impl Parse for Riscv { return Err(SVDError::NotExpectedTag("riscv".to_string()).at(tree.id())); } - let mut builder = Riscv::builder() - .clic(tree.get_child_text("clic").ok()) - .clint(tree.get_child_text("clint").ok()) - .plic(tree.get_child_text("plic").ok()); + let mut builder = Riscv::builder(); if let Some(interrupts) = tree.get_child("coreInterrupts") { let interrupts: Result, _> = interrupts diff --git a/svd-rs/CHANGELOG.md b/svd-rs/CHANGELOG.md index 73f4e36c..4e61645f 100644 --- a/svd-rs/CHANGELOG.md +++ b/svd-rs/CHANGELOG.md @@ -8,6 +8,7 @@ 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 diff --git a/svd-rs/Cargo.toml b/svd-rs/Cargo.toml index 29163403..3f8488b2 100644 --- a/svd-rs/Cargo.toml +++ b/svd-rs/Cargo.toml @@ -15,6 +15,7 @@ readme = "README.md" [features] derive-from = [] +unstable-riscv = [] [dependencies] thiserror = "1.0.31" diff --git a/svd-rs/src/device.rs b/svd-rs/src/device.rs index 224383fd..d7f9b0a8 100644 --- a/svd-rs/src/device.rs +++ b/svd-rs/src/device.rs @@ -1,6 +1,8 @@ +#[cfg(feature = "unstable-riscv")] +use super::Riscv; use super::{ - BuildError, Cpu, Description, EmptyToNone, Name, Peripheral, RegisterProperties, Riscv, - SvdError, ValidateLevel, + BuildError, Cpu, Description, EmptyToNone, Name, Peripheral, RegisterProperties, SvdError, + ValidateLevel, }; /// Errors for [`Device::validate`] @@ -111,6 +113,7 @@ pub struct Device { feature = "serde", serde(default, skip_serializing_if = "Option::is_none") )] + #[cfg(feature = "unstable-riscv")] pub riscv: Option, } @@ -137,6 +140,7 @@ pub struct DeviceBuilder { version: Option, description: Option, license_text: Option, + #[cfg(feature = "unstable-riscv")] riscv: Option, cpu: Option, header_system_filename: Option, @@ -160,6 +164,7 @@ impl From 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, @@ -212,8 +217,9 @@ impl DeviceBuilder { self } /// Set the riscv of the device. - pub fn riscv(mut self, value: Option) -> Self { - self.riscv = value; + #[cfg(feature = "unstable-riscv")] + pub fn riscv(mut self, value: Riscv) -> Self { + self.riscv = Some(value); self } /// Set the cpu of the device. @@ -297,6 +303,7 @@ 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, @@ -356,6 +363,7 @@ 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; } diff --git a/svd-rs/src/lib.rs b/svd-rs/src/lib.rs index d59f35c9..ceaf9e54 100644 --- a/svd-rs/src/lib.rs +++ b/svd-rs/src/lib.rs @@ -95,7 +95,9 @@ 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 diff --git a/svd-rs/src/riscv.rs b/svd-rs/src/riscv.rs index b8eee6ee..7398ec9e 100644 --- a/svd-rs/src/riscv.rs +++ b/svd-rs/src/riscv.rs @@ -18,27 +18,6 @@ pub use priority::Priority; #[derive(Clone, Debug, PartialEq, Eq)] #[non_exhaustive] pub struct Riscv { - /// Indicate the ID of the CLIC peripheral (if present). - #[cfg_attr( - feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") - )] - pub clic: Option, - - /// Indicate the ID of the CLINT peripheral (if present). - #[cfg_attr( - feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") - )] - pub clint: Option, - - /// Indicate the ID of the PLIC peripheral (if present). - #[cfg_attr( - feature = "serde", - serde(default, skip_serializing_if = "Option::is_none") - )] - pub plic: Option, - /// Core interrupt enumeration values #[cfg_attr( feature = "serde", @@ -64,9 +43,6 @@ pub struct Riscv { /// Builder for [`Riscv`] #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct RiscvBuilder { - clic: Option, - clint: Option, - plic: Option, core_interrupts: Option>, priorities: Option>, harts: Option>, @@ -75,9 +51,6 @@ pub struct RiscvBuilder { impl From for RiscvBuilder { fn from(riscv: Riscv) -> Self { Self { - clic: riscv.clic, - clint: riscv.clint, - plic: riscv.plic, core_interrupts: Some(riscv.core_interrupts), priorities: Some(riscv.priorities), harts: Some(riscv.harts), @@ -86,24 +59,6 @@ impl From for RiscvBuilder { } impl RiscvBuilder { - /// Set the ID of the CLIC peripheral - pub fn clic(mut self, clic: Option) -> Self { - self.clic = clic; - self - } - - /// Set the ID of the CLINT peripheral - pub fn clint(mut self, clint: Option) -> Self { - self.clint = clint; - self - } - - /// Set the ID of the PLIC peripheral - pub fn plic(mut self, plic: Option) -> Self { - self.plic = plic; - self - } - /// Set the core interrupt enumeration values pub fn core_interrupts(mut self, core_interrupts: Vec) -> Self { self.core_interrupts = Some(core_interrupts); @@ -125,9 +80,6 @@ impl RiscvBuilder { /// Validate and build a [`Riscv`]. pub fn build(self, lvl: ValidateLevel) -> Result { let riscv = Riscv { - clic: self.clic, - clint: self.clint, - plic: self.plic, core_interrupts: self .core_interrupts .ok_or_else(|| BuildError::Uninitialized("core_interrupts".to_string()))?, @@ -155,15 +107,6 @@ impl Riscv { builder: RiscvBuilder, lvl: ValidateLevel, ) -> Result<(), SvdError> { - if builder.clic.is_some() { - self.clic = builder.clic; - } - if builder.clint.is_some() { - self.clint = builder.clint; - } - if builder.plic.is_some() { - self.plic = builder.plic; - } if let Some(core_interrupts) = builder.core_interrupts { self.core_interrupts = core_interrupts; } diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 9ceb2a9a..8556f80a 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -7,6 +7,9 @@ edition = "2021" version = "0.12.0" publish = false +[features] +unstable-riscv = ["svd-rs/unstable-riscv", "svd-parser/unstable-riscv", "svd-encoder/unstable-riscv"] + [dependencies] svd-rs = { path = "../svd-rs"} svd-parser = { path = "../svd-parser"} diff --git a/tests/src/lib.rs b/tests/src/lib.rs index c23fd2d0..7e0ed121 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -62,4 +62,5 @@ mod register; mod usage; mod writeconstraint; +#[cfg(feature = "unstable-riscv")] mod riscv; diff --git a/tests/src/riscv.rs b/tests/src/riscv.rs index 39796e9f..e4b26d5a 100644 --- a/tests/src/riscv.rs +++ b/tests/src/riscv.rs @@ -1,5 +1,3 @@ -use std::vec; - use super::run_test; use crate::svd::{ riscv::{Hart, Priority, Riscv}, @@ -89,8 +87,6 @@ fn decode_encode() { let tests = vec![( Riscv::builder() - .clint(Some("CLINT".to_string())) - .plic(Some("PLIC".to_string())) .core_interrupts(interrupts) .priorities(priorities) .harts(harts) @@ -98,8 +94,6 @@ fn decode_encode() { .unwrap(), " - CLINT - PLIC MachineSoft @@ -170,8 +164,6 @@ fn decode_encode() { ", " - CLINT - PLIC MachineSoft