1use crate::arm::register::{ApRegister, ReadableRegister, RegisterDescriptor, WritableRegister};
8use crate::register_data_rw;
9use alloc::{format, string::String};
10use core::fmt;
11
12pub struct CswRegister;
14
15impl RegisterDescriptor for CswRegister {
16 const ADDRESS: u8 = 0x00;
17 type Value = Csw;
18}
19
20impl ReadableRegister for CswRegister {}
21impl WritableRegister for CswRegister {}
22impl ApRegister for CswRegister {}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct Csw(u32);
27
28register_data_rw!(Csw);
30
31impl Csw {
32 const SIZE_MASK: u32 = 0b111;
34 const SIZE_SHIFT: u32 = 0;
35
36 const ADDRINC_MASK: u32 = 0b11;
37 const ADDRINC_SHIFT: u32 = 4;
38
39 const DEVICE_EN: u32 = 1 << 6;
40 const TR_IN_PROG: u32 = 1 << 7;
41
42 const MODE_MASK: u32 = 0b1111;
43 const MODE_SHIFT: u32 = 8;
44
45 const TYPE_MASK: u32 = 0b111;
46 const TYPE_SHIFT: u32 = 12;
47
48 const MTE: u32 = 1 << 15;
49
50 const SPIDEN: u32 = 1 << 23;
52
53 const PROT_MASK: u32 = 0b1111111;
54 const PROT_SHIFT: u32 = 24;
55
56 const DBG_SW_ENABLE: u32 = 1 << 31;
57
58 const RESERVED_HIGH: u32 = 1 << 24;
59
60 pub const SIZE_8BIT: u32 = 0b000;
62 pub const SIZE_16BIT: u32 = 0b001;
63 pub const SIZE_32BIT: u32 = 0b010;
64 pub const SIZE_64BIT: u32 = 0b011;
65 pub const SIZE_128BIT: u32 = 0b100;
66 pub const SIZE_256BIT: u32 = 0b101;
67
68 pub const ADDRINC_OFF: u32 = 0b00;
70 pub const ADDRINC_SINGLE: u32 = 0b01;
71 pub const ADDRINC_PACKED: u32 = 0b10;
72
73 pub const PROT_MASTER_DEBUG: u32 = 1 << 5;
75 pub const PROT_BIT_1: u32 = 1 << 1;
76
77 pub fn value(&self) -> u32 {
79 self.0
80 }
81
82 pub fn size(&self) -> u32 {
84 (self.0 >> Self::SIZE_SHIFT) & Self::SIZE_MASK
85 }
86
87 pub fn addrinc(&self) -> u32 {
89 (self.0 >> Self::ADDRINC_SHIFT) & Self::ADDRINC_MASK
90 }
91
92 pub fn device_en(&self) -> bool {
94 self.0 & Self::DEVICE_EN != 0
95 }
96
97 pub fn tr_in_prog(&self) -> bool {
99 self.0 & Self::TR_IN_PROG != 0
100 }
101
102 pub fn mode(&self) -> u32 {
104 (self.0 >> Self::MODE_SHIFT) & Self::MODE_MASK
105 }
106
107 pub fn type_bits(&self) -> u32 {
109 (self.0 >> Self::TYPE_SHIFT) & Self::TYPE_MASK
110 }
111
112 pub fn mte(&self) -> bool {
114 self.0 & Self::MTE != 0
115 }
116
117 pub fn spiden(&self) -> bool {
119 self.0 & Self::SPIDEN != 0
120 }
121
122 pub fn prot(&self) -> u32 {
124 (self.0 >> Self::PROT_SHIFT) & Self::PROT_MASK
125 }
126
127 pub fn dbg_sw_enable(&self) -> bool {
129 self.0 & Self::DBG_SW_ENABLE != 0
130 }
131
132 pub fn set_reserved_high(&mut self) {
134 self.0 |= Self::RESERVED_HIGH;
135 }
136
137 pub fn set_size(&mut self, size: u32) {
139 self.0 = (self.0 & !(Self::SIZE_MASK << Self::SIZE_SHIFT))
140 | ((size & Self::SIZE_MASK) << Self::SIZE_SHIFT);
141 }
142
143 pub fn set_addrinc(&mut self, addrinc: u32) {
145 self.0 = (self.0 & !(Self::ADDRINC_MASK << Self::ADDRINC_SHIFT))
146 | ((addrinc & Self::ADDRINC_MASK) << Self::ADDRINC_SHIFT);
147 }
148
149 pub fn set_device_en(&mut self, enable: bool) {
151 if enable {
152 self.0 |= Self::DEVICE_EN;
153 } else {
154 self.0 &= !Self::DEVICE_EN;
155 }
156 }
157
158 pub fn set_mode(&mut self, mode: u32) {
160 self.0 = (self.0 & !(Self::MODE_MASK << Self::MODE_SHIFT))
161 | ((mode & Self::MODE_MASK) << Self::MODE_SHIFT);
162 }
163
164 pub fn set_type(&mut self, type_bits: u32) {
166 self.0 = (self.0 & !(Self::TYPE_MASK << Self::TYPE_SHIFT))
167 | ((type_bits & Self::TYPE_MASK) << Self::TYPE_SHIFT);
168 }
169
170 pub fn set_mte(&mut self, enable: bool) {
172 if enable {
173 self.0 |= Self::MTE;
174 } else {
175 self.0 &= !Self::MTE;
176 }
177 }
178
179 pub fn set_spiden(&mut self, enable: bool) {
181 if enable {
182 self.0 |= Self::SPIDEN;
183 } else {
184 self.0 &= !Self::SPIDEN;
185 }
186 }
187
188 pub fn set_prot(&mut self, prot: u32) {
190 self.0 = (self.0 & !(Self::PROT_MASK << Self::PROT_SHIFT))
191 | ((prot & Self::PROT_MASK) << Self::PROT_SHIFT);
192 }
193
194 pub fn set_dbg_sw_enable(&mut self, enable: bool) {
196 if enable {
197 self.0 |= Self::DBG_SW_ENABLE;
198 } else {
199 self.0 &= !Self::DBG_SW_ENABLE;
200 }
201 }
202
203 pub fn transfer_config(&self) -> String {
205 let size = match self.size() {
206 Self::SIZE_8BIT => "8-bit",
207 Self::SIZE_16BIT => "16-bit",
208 Self::SIZE_32BIT => "32-bit",
209 Self::SIZE_64BIT => "64-bit",
210 Self::SIZE_128BIT => "128-bit",
211 Self::SIZE_256BIT => "256-bit",
212 _ => "Reserved",
213 };
214
215 let addrinc = match self.addrinc() {
216 Self::ADDRINC_OFF => "Off",
217 Self::ADDRINC_SINGLE => "Single",
218 Self::ADDRINC_PACKED => "Packed",
219 _ => "Reserved",
220 };
221
222 format!("Size: {size}, AddrInc: {addrinc}")
223 }
224
225 pub fn status_flags(&self) -> String {
227 let mut flags = [""; 6];
228 let mut count = 0;
229
230 if self.device_en() {
231 flags[count] = "DEVICE_EN";
232 count += 1;
233 }
234 if self.tr_in_prog() {
235 flags[count] = "TR_IN_PROG";
236 count += 1;
237 }
238 if self.mte() {
239 flags[count] = "MTE";
240 count += 1;
241 }
242 if self.spiden() {
243 flags[count] = "SPIDEN";
244 count += 1;
245 }
246 if self.dbg_sw_enable() {
247 flags[count] = "DBG_SW_ENABLE";
248 count += 1;
249 }
250
251 if count == 0 {
252 "No flags set".into()
253 } else {
254 format!("Flags: {}", flags[..count].join(", "))
255 }
256 }
257
258 pub fn security_state(&self) -> String {
260 format!(
261 "PROT: 0x{:02x}, SPIDEN: {}, DBG_SW: {}",
262 self.prot(),
263 if self.spiden() { "Y" } else { "N" },
264 if self.dbg_sw_enable() { "Y" } else { "N" }
265 )
266 }
267}
268
269impl Default for Csw {
270 fn default() -> Self {
271 let mut csw = Csw(0);
272 csw.set_reserved_high();
273 csw.set_prot(Self::PROT_MASTER_DEBUG | Self::PROT_BIT_1);
274 csw.set_size(Self::SIZE_32BIT);
275 csw.set_addrinc(Self::ADDRINC_OFF);
276 csw.set_device_en(true);
277
278 csw
279 }
280}
281
282pub struct TarRegister;
284
285impl RegisterDescriptor for TarRegister {
286 const ADDRESS: u8 = 0x04;
287 type Value = Tar;
288}
289
290impl ReadableRegister for TarRegister {}
291impl WritableRegister for TarRegister {}
292impl ApRegister for TarRegister {}
293
294#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
296pub struct Tar(u32);
297
298register_data_rw!(Tar);
300
301impl Tar {
302 pub fn value(&self) -> u32 {
304 self.0
305 }
306
307 pub fn target_address(&self) -> u32 {
309 self.0
310 }
311
312 pub fn set_target_address(&mut self, address: u32) {
314 self.0 = address;
315 }
316}
317
318pub struct DrwRegister;
320
321impl RegisterDescriptor for DrwRegister {
322 const ADDRESS: u8 = 0x0C;
323 type Value = Drw;
324}
325
326impl ReadableRegister for DrwRegister {}
327impl WritableRegister for DrwRegister {}
328impl ApRegister for DrwRegister {}
329
330#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
332pub struct Drw(u32);
333
334register_data_rw!(Drw);
336
337impl Drw {
338 pub fn value(&self) -> u32 {
340 self.0
341 }
342
343 pub fn data(&self) -> u32 {
345 self.0
346 }
347
348 pub fn set_data(&mut self, data: u32) {
350 self.0 = data;
351 }
352}
353
354pub struct Bd0Register;
356
357impl RegisterDescriptor for Bd0Register {
358 const ADDRESS: u8 = 0x10;
359 type Value = BankedData;
360}
361
362impl ReadableRegister for Bd0Register {}
363impl WritableRegister for Bd0Register {}
364impl ApRegister for Bd0Register {}
365
366pub struct Bd1Register;
368
369impl RegisterDescriptor for Bd1Register {
370 const ADDRESS: u8 = 0x14;
371 type Value = BankedData;
372}
373
374impl ReadableRegister for Bd1Register {}
375impl WritableRegister for Bd1Register {}
376impl ApRegister for Bd1Register {}
377
378pub struct Bd2Register;
380
381impl RegisterDescriptor for Bd2Register {
382 const ADDRESS: u8 = 0x18;
383 type Value = BankedData;
384}
385
386impl ReadableRegister for Bd2Register {}
387impl WritableRegister for Bd2Register {}
388impl ApRegister for Bd2Register {}
389
390pub struct Bd3Register;
392
393impl RegisterDescriptor for Bd3Register {
394 const ADDRESS: u8 = 0x1C;
395 type Value = BankedData;
396}
397
398impl ReadableRegister for Bd3Register {}
399impl WritableRegister for Bd3Register {}
400impl ApRegister for Bd3Register {}
401
402#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
408pub struct BankedData(u32);
409
410register_data_rw!(BankedData);
412
413impl BankedData {
414 pub fn data(&self) -> u32 {
416 self.0
417 }
418
419 pub fn set_data(&mut self, data: u32) {
421 self.0 = data;
422 }
423}