Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions svd-encoder/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion svd-encoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
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()));
}

// 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)?));
Expand Down
1 change: 1 addition & 0 deletions svd-encoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,6 @@ mod readaction;
mod register;
mod registercluster;
mod registerproperties;
mod riscv;
mod usage;
mod writeconstraint;
79 changes: 79 additions & 0 deletions svd-encoder/src/riscv.rs
Original file line number Diff line number Diff line change
@@ -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<Element, EncodeError> {
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<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)
}
}
1 change: 1 addition & 0 deletions svd-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion svd-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 4 additions & 1 deletion svd-parser/src/device.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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>("riscv", tree, config)?)
.cpu(optional::<Cpu>("cpu", tree, config)?)
.header_system_filename(tree.get_child_text_opt("headerSystemFilename")?)
.header_definitions_prefix(tree.get_child_text_opt("headerDefinitionsPrefix")?)
Expand Down
1 change: 1 addition & 0 deletions svd-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ mod readaction;
mod register;
mod registercluster;
mod registerproperties;
mod riscv;
mod usage;
mod writeconstraint;

Expand Down
88 changes: 88 additions & 0 deletions svd-parser/src/riscv.rs
Original file line number Diff line number Diff line change
@@ -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<Self, Self::Error> {
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<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()))
}
}
1 change: 1 addition & 0 deletions svd-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 20 additions & 2 deletions svd-rs/src/device.rs
Original file line number Diff line number Diff line change
@@ -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`]
Expand Down Expand Up @@ -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<Riscv>,
}

fn default_xmlns_xs() -> String {
Expand All @@ -130,6 +137,7 @@ pub struct DeviceBuilder {
version: Option<String>,
description: Option<String>,
license_text: Option<String>,
riscv: Option<Riscv>,
cpu: Option<Cpu>,
header_system_filename: Option<String>,
header_definitions_prefix: Option<String>,
Expand All @@ -152,6 +160,7 @@ impl From<Device> 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,
Expand Down Expand Up @@ -202,6 +211,11 @@ impl DeviceBuilder {
self.license_text = value;
self
}
/// Set the riscv of the device.
pub fn riscv(mut self, value: Option<Riscv>) -> Self {
self.riscv = 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 +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,
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions svd-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ pub use self::protection::Protection;
pub mod datatype;
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)]
pub enum ValidateLevel {
Expand Down
Loading