Skip to content

Commit f4376aa

Browse files
authored
Merge pull request #265 from romancardenas/master
Add `riscv` section for RISC-V targets
2 parents 8194739 + ddc3d99 commit f4376aa

File tree

20 files changed

+827
-0
lines changed

20 files changed

+827
-0
lines changed

svd-encoder/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

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

1214
## [v0.14.3] - 2023-11-15

svd-encoder/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ rust-version = "1.65.0"
1111
version = "0.14.4"
1212
readme = "README.md"
1313

14+
[features]
15+
unstable-riscv = ["svd-rs/unstable-riscv"]
16+
1417
[dependencies]
1518
convert_case = "0.6.0"
1619
svd-rs = { version = "0.14.7", path = "../svd-rs" }

svd-encoder/src/device.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ impl Encode for Device {
3434
elem.children.push(new_node("licenseText", v.clone()));
3535
}
3636

37+
#[cfg(feature = "unstable-riscv")]
38+
if let Some(v) = &self.riscv {
39+
elem.children
40+
.push(XMLNode::Element(v.encode_with_config(config)?));
41+
}
42+
3743
if let Some(v) = &self.cpu {
3844
elem.children
3945
.push(XMLNode::Element(v.encode_with_config(config)?));

svd-encoder/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,7 @@ mod readaction;
103103
mod register;
104104
mod registercluster;
105105
mod registerproperties;
106+
#[cfg(feature = "unstable-riscv")]
107+
mod riscv;
106108
mod usage;
107109
mod writeconstraint;

svd-encoder/src/riscv.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use super::{new_node, Config, Element, Encode, EncodeError, XMLNode};
2+
use crate::svd::riscv::{Hart, Priority, Riscv};
3+
4+
impl Encode for Riscv {
5+
type Error = EncodeError;
6+
7+
fn encode_with_config(&self, config: &Config) -> Result<Element, EncodeError> {
8+
let mut elem = Element::new("riscv");
9+
10+
if !self.core_interrupts.is_empty() {
11+
let mut interrupts = Element::new("coreInterrupts");
12+
for interrupt in &self.core_interrupts {
13+
interrupts
14+
.children
15+
.push(interrupt.encode_node_with_config(config)?);
16+
}
17+
elem.children.push(XMLNode::Element(interrupts));
18+
}
19+
if !self.priorities.is_empty() {
20+
let mut priorities = Element::new("priorities");
21+
for priority in &self.priorities {
22+
priorities
23+
.children
24+
.push(priority.encode_node_with_config(config)?);
25+
}
26+
elem.children.push(XMLNode::Element(priorities));
27+
}
28+
if !self.harts.is_empty() {
29+
let mut harts = Element::new("harts");
30+
for hart in &self.harts {
31+
harts.children.push(hart.encode_node_with_config(config)?);
32+
}
33+
elem.children.push(XMLNode::Element(harts));
34+
}
35+
36+
Ok(elem)
37+
}
38+
}
39+
40+
impl Encode for Priority {
41+
type Error = EncodeError;
42+
43+
fn encode_with_config(&self, _config: &Config) -> Result<Element, EncodeError> {
44+
let mut children = vec![new_node("name", self.name.clone())];
45+
if let Some(desc) = &self.description {
46+
children.push(new_node("description", desc.clone()));
47+
}
48+
children.push(new_node("value", format!("{}", self.value)));
49+
50+
let mut elem = Element::new("priority");
51+
elem.children = children;
52+
Ok(elem)
53+
}
54+
}
55+
56+
impl Encode for Hart {
57+
type Error = EncodeError;
58+
59+
fn encode_with_config(&self, _config: &Config) -> Result<Element, EncodeError> {
60+
let mut children = vec![new_node("name", self.name.clone())];
61+
if let Some(desc) = &self.description {
62+
children.push(new_node("description", desc.clone()));
63+
}
64+
children.push(new_node("value", format!("{}", self.value)));
65+
66+
let mut elem = Element::new("hart");
67+
elem.children = children;
68+
Ok(elem)
69+
}
70+
}

svd-parser/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

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

1214
## [v0.14.5] - 2024-01-03

svd-parser/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ readme = "README.md"
1717
[features]
1818
derive-from = ["svd-rs/derive-from"]
1919
expand = ["derive-from"]
20+
unstable-riscv = ["svd-rs/unstable-riscv"]
2021

2122
[dependencies]
2223
svd-rs = { version = "0.14.7", path = "../svd-rs" }

svd-parser/src/device.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use super::*;
2+
#[cfg(feature = "unstable-riscv")]
3+
use crate::svd::riscv::Riscv;
24
use crate::svd::{cpu::Cpu, peripheral::Peripheral, registerproperties::RegisterProperties};
35

46
/// Parses a SVD file
@@ -31,6 +33,10 @@ impl Parse for Device {
3133
.collect();
3234
ps?
3335
});
36+
#[cfg(feature = "unstable-riscv")]
37+
if let Some(riscv) = optional::<Riscv>("riscv", tree, config)? {
38+
device = device.riscv(riscv);
39+
}
3440
if let Some(version) = tree.get_child_text_opt("version")? {
3541
device = device.version(version)
3642
}

svd-parser/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ mod readaction;
211211
mod register;
212212
mod registercluster;
213213
mod registerproperties;
214+
#[cfg(feature = "unstable-riscv")]
215+
mod riscv;
214216
mod usage;
215217
mod writeconstraint;
216218

svd-parser/src/riscv.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use super::*;
2+
use crate::svd::riscv::{Hart, Interrupt, Priority, Riscv};
3+
4+
impl Parse for Riscv {
5+
type Object = Self;
6+
type Error = SVDErrorAt;
7+
type Config = Config;
8+
9+
fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
10+
if !tree.has_tag_name("riscv") {
11+
return Err(SVDError::NotExpectedTag("riscv".to_string()).at(tree.id()));
12+
}
13+
14+
let mut builder = Riscv::builder();
15+
16+
if let Some(interrupts) = tree.get_child("coreInterrupts") {
17+
let interrupts: Result<Vec<_>, _> = interrupts
18+
.children()
19+
.filter(|t| t.is_element() && t.has_tag_name("interrupt"))
20+
.map(|i| Interrupt::parse(&i, config))
21+
.collect();
22+
builder = builder.core_interrupts(interrupts?);
23+
}
24+
25+
if let Some(priorities) = tree.get_child("priorities") {
26+
let priorities: Result<Vec<_>, _> = priorities
27+
.children()
28+
.filter(|t| t.is_element() && t.has_tag_name("priority"))
29+
.map(|i| Priority::parse(&i, config))
30+
.collect();
31+
builder = builder.priorities(priorities?);
32+
};
33+
34+
if let Some(harts) = tree.get_child("harts") {
35+
let harts: Result<Vec<_>, _> = harts
36+
.children()
37+
.filter(|t| t.is_element() && t.has_tag_name("hart"))
38+
.map(|i| Hart::parse(&i, config))
39+
.collect();
40+
builder = builder.harts(harts?);
41+
};
42+
43+
builder
44+
.build(config.validate_level)
45+
.map_err(|e| SVDError::from(e).at(tree.id()))
46+
}
47+
}
48+
49+
impl Parse for Priority {
50+
type Object = Self;
51+
type Error = SVDErrorAt;
52+
type Config = Config;
53+
54+
fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
55+
if !tree.has_tag_name("priority") {
56+
return Err(SVDError::NotExpectedTag("priority".to_string()).at(tree.id()));
57+
}
58+
59+
Priority::builder()
60+
.name(tree.get_child_text("name")?)
61+
.description(tree.get_child_text_opt("description")?)
62+
.value(tree.get_child_u32("value")?)
63+
.build(config.validate_level)
64+
.map_err(|e| SVDError::from(e).at(tree.id()))
65+
}
66+
}
67+
68+
impl Parse for Hart {
69+
type Object = Self;
70+
type Error = SVDErrorAt;
71+
type Config = Config;
72+
73+
fn parse(tree: &Node, config: &Config) -> Result<Self, Self::Error> {
74+
if !tree.has_tag_name("hart") {
75+
return Err(SVDError::NotExpectedTag("hart".to_string()).at(tree.id()));
76+
}
77+
78+
Hart::builder()
79+
.name(tree.get_child_text("name")?)
80+
.description(tree.get_child_text_opt("description")?)
81+
.value(tree.get_child_u32("value")?)
82+
.build(config.validate_level)
83+
.map_err(|e| SVDError::from(e).at(tree.id()))
84+
}
85+
}

0 commit comments

Comments
 (0)