1use super::{BuildError, Endian, SvdError, ValidateLevel};
2#[cfg_attr(
4 feature = "serde",
5 derive(serde::Deserialize, serde::Serialize),
6 serde(rename_all = "camelCase")
7)]
8#[derive(Clone, Debug, PartialEq, Eq)]
9#[non_exhaustive]
10pub struct Cpu {
11 pub name: String,
13
14 pub revision: String,
16
17 pub endian: Endian,
19
20 pub mpu_present: bool,
22
23 pub fpu_present: bool,
25
26 #[cfg_attr(
29 feature = "serde",
30 serde(default, skip_serializing_if = "Option::is_none", rename = "fpuDP")
31 )]
32 pub fpu_double_precision: Option<bool>,
33
34 #[cfg_attr(
36 feature = "serde",
37 serde(default, skip_serializing_if = "Option::is_none")
38 )]
39 pub dsp_present: Option<bool>,
40
41 #[cfg_attr(
43 feature = "serde",
44 serde(default, skip_serializing_if = "Option::is_none")
45 )]
46 pub icache_present: Option<bool>,
47
48 #[cfg_attr(
50 feature = "serde",
51 serde(default, skip_serializing_if = "Option::is_none")
52 )]
53 pub dcache_present: Option<bool>,
54
55 #[cfg_attr(
57 feature = "serde",
58 serde(default, skip_serializing_if = "Option::is_none")
59 )]
60 pub itcm_present: Option<bool>,
61
62 #[cfg_attr(
64 feature = "serde",
65 serde(default, skip_serializing_if = "Option::is_none")
66 )]
67 pub dtcm_present: Option<bool>,
68
69 #[cfg_attr(
72 feature = "serde",
73 serde(default, skip_serializing_if = "Option::is_none")
74 )]
75 pub vtor_present: Option<bool>,
76
77 #[cfg_attr(feature = "serde", serde(rename = "nvicPrioBits"))]
79 pub nvic_priority_bits: u32,
80
81 #[cfg_attr(feature = "serde", serde(rename = "vendorSystickConfig"))]
83 pub has_vendor_systick: bool,
84
85 #[cfg_attr(
87 feature = "serde",
88 serde(default, skip_serializing_if = "Option::is_none")
89 )]
90 pub device_num_interrupts: Option<u32>,
91
92 #[cfg_attr(
94 feature = "serde",
95 serde(default, skip_serializing_if = "Option::is_none")
96 )]
97 pub sau_num_regions: Option<u32>,
98 }
100
101#[derive(Clone, Debug, Default, PartialEq, Eq)]
103pub struct CpuBuilder {
104 name: Option<String>,
105 revision: Option<String>,
106 endian: Option<Endian>,
107 mpu_present: Option<bool>,
108 fpu_present: Option<bool>,
109 fpu_double_precision: Option<bool>,
110 dsp_present: Option<bool>,
111 icache_present: Option<bool>,
112 dcache_present: Option<bool>,
113 itcm_present: Option<bool>,
114 dtcm_present: Option<bool>,
115 vtor_present: Option<bool>,
116 nvic_priority_bits: Option<u32>,
117 has_vendor_systick: Option<bool>,
118 device_num_interrupts: Option<u32>,
119 sau_num_regions: Option<u32>,
120}
121
122impl From<Cpu> for CpuBuilder {
123 fn from(c: Cpu) -> Self {
124 Self {
125 name: Some(c.name),
126 revision: Some(c.revision),
127 endian: Some(c.endian),
128 mpu_present: Some(c.mpu_present),
129 fpu_present: Some(c.fpu_present),
130 fpu_double_precision: c.fpu_double_precision,
131 dsp_present: c.dsp_present,
132 icache_present: c.icache_present,
133 dcache_present: c.dcache_present,
134 itcm_present: c.itcm_present,
135 dtcm_present: c.dtcm_present,
136 vtor_present: c.vtor_present,
137 nvic_priority_bits: Some(c.nvic_priority_bits),
138 has_vendor_systick: Some(c.has_vendor_systick),
139 device_num_interrupts: c.device_num_interrupts,
140 sau_num_regions: c.sau_num_regions,
141 }
142 }
143}
144
145impl CpuBuilder {
146 pub fn name(mut self, value: String) -> Self {
148 self.name = Some(value);
149 self
150 }
151 pub fn revision(mut self, value: String) -> Self {
153 self.revision = Some(value);
154 self
155 }
156 pub fn endian(mut self, value: Endian) -> Self {
158 self.endian = Some(value);
159 self
160 }
161 pub fn mpu_present(mut self, value: bool) -> Self {
163 self.mpu_present = Some(value);
164 self
165 }
166 pub fn fpu_present(mut self, value: bool) -> Self {
168 self.fpu_present = Some(value);
169 self
170 }
171 pub fn fpu_double_precision(mut self, value: Option<bool>) -> Self {
173 self.fpu_double_precision = value;
174 self
175 }
176 pub fn dsp_present(mut self, value: Option<bool>) -> Self {
178 self.dsp_present = value;
179 self
180 }
181 pub fn icache_present(mut self, value: Option<bool>) -> Self {
183 self.icache_present = value;
184 self
185 }
186 pub fn dcache_present(mut self, value: Option<bool>) -> Self {
188 self.dcache_present = value;
189 self
190 }
191 pub fn itcm_present(mut self, value: Option<bool>) -> Self {
193 self.itcm_present = value;
194 self
195 }
196 pub fn dtcm_present(mut self, value: Option<bool>) -> Self {
198 self.dtcm_present = value;
199 self
200 }
201 pub fn vtor_present(mut self, value: Option<bool>) -> Self {
203 self.vtor_present = value;
204 self
205 }
206 pub fn nvic_priority_bits(mut self, value: u32) -> Self {
208 self.nvic_priority_bits = Some(value);
209 self
210 }
211 pub fn has_vendor_systick(mut self, value: bool) -> Self {
213 self.has_vendor_systick = Some(value);
214 self
215 }
216 pub fn device_num_interrupts(mut self, value: Option<u32>) -> Self {
218 self.device_num_interrupts = value;
219 self
220 }
221 pub fn sau_num_regions(mut self, value: Option<u32>) -> Self {
223 self.sau_num_regions = value;
224 self
225 }
226 pub fn build(self, lvl: ValidateLevel) -> Result<Cpu, SvdError> {
228 let cpu = Cpu {
229 name: self
230 .name
231 .ok_or_else(|| BuildError::Uninitialized("name".to_string()))?,
232 revision: self
233 .revision
234 .ok_or_else(|| BuildError::Uninitialized("revision".to_string()))?,
235 endian: self
236 .endian
237 .ok_or_else(|| BuildError::Uninitialized("endian".to_string()))?,
238 mpu_present: self
239 .mpu_present
240 .ok_or_else(|| BuildError::Uninitialized("mpu_present".to_string()))?,
241 fpu_present: self
242 .fpu_present
243 .ok_or_else(|| BuildError::Uninitialized("fpu_present".to_string()))?,
244 fpu_double_precision: self.fpu_double_precision,
245 dsp_present: self.dsp_present,
246 icache_present: self.icache_present,
247 dcache_present: self.dcache_present,
248 itcm_present: self.itcm_present,
249 dtcm_present: self.dtcm_present,
250 vtor_present: self.vtor_present,
251 nvic_priority_bits: self
252 .nvic_priority_bits
253 .ok_or_else(|| BuildError::Uninitialized("nvic_priority_bits".to_string()))?,
254 has_vendor_systick: self
255 .has_vendor_systick
256 .ok_or_else(|| BuildError::Uninitialized("has_vendor_systick".to_string()))?,
257 device_num_interrupts: self.device_num_interrupts,
258 sau_num_regions: self.sau_num_regions,
259 };
260 cpu.validate(lvl)?;
261 Ok(cpu)
262 }
263}
264
265impl Cpu {
266 pub fn builder() -> CpuBuilder {
268 CpuBuilder::default()
269 }
270 pub fn modify_from(&mut self, builder: CpuBuilder, lvl: ValidateLevel) -> Result<(), SvdError> {
272 if let Some(name) = builder.name {
273 self.name = name;
274 }
275 if let Some(revision) = builder.revision {
276 self.revision = revision;
277 }
278 if let Some(endian) = builder.endian {
279 self.endian = endian;
280 }
281 if let Some(mpu_present) = builder.mpu_present {
282 self.mpu_present = mpu_present;
283 }
284 if let Some(fpu_present) = builder.fpu_present {
285 self.fpu_present = fpu_present;
286 }
287 if builder.fpu_double_precision.is_some() {
288 self.fpu_double_precision = builder.fpu_double_precision;
289 }
290 if builder.dsp_present.is_some() {
291 self.dsp_present = builder.dsp_present;
292 }
293 if builder.icache_present.is_some() {
294 self.icache_present = builder.icache_present;
295 }
296 if builder.dcache_present.is_some() {
297 self.dcache_present = builder.dcache_present;
298 }
299 if builder.itcm_present.is_some() {
300 self.itcm_present = builder.itcm_present;
301 }
302 if builder.dtcm_present.is_some() {
303 self.dtcm_present = builder.dtcm_present;
304 }
305 if builder.vtor_present.is_some() {
306 self.vtor_present = builder.vtor_present;
307 }
308 if let Some(nvic_priority_bits) = builder.nvic_priority_bits {
309 self.nvic_priority_bits = nvic_priority_bits;
310 }
311 if let Some(has_vendor_systick) = builder.has_vendor_systick {
312 self.has_vendor_systick = has_vendor_systick;
313 }
314 if builder.device_num_interrupts.is_some() {
315 self.device_num_interrupts = builder.device_num_interrupts;
316 }
317 if builder.sau_num_regions.is_some() {
318 self.sau_num_regions = builder.sau_num_regions;
319 }
320 self.validate(lvl)
321 }
322 pub fn validate(&self, _lvl: ValidateLevel) -> Result<(), SvdError> {
324 Ok(())
326 }
327 pub fn is_cortex_m(&self) -> bool {
329 self.name.starts_with("CM")
330 }
331}