1use core::marker::PhantomData;
8
9use tock_registers::fields::Field;
10use tock_registers::interfaces::{Readable, Writeable};
11use tock_registers::{RegisterLongName, UIntLike};
12
13pub const MINSTRETH: usize = 0xB82;
14pub const MINSTRET: usize = 0xB02;
15pub const MCYCLEH: usize = 0xB80;
16pub const MCYCLE: usize = 0xB00;
17pub const MIE: usize = 0x304;
18pub const MTVEC: usize = 0x305;
19pub const MSTATUS: usize = 0x300;
20pub const UTVEC: usize = 0x005;
21pub const STVEC: usize = 0x105;
22pub const MSCRATCH: usize = 0x340;
23pub const MEPC: usize = 0x341;
24pub const MCAUSE: usize = 0x342;
25pub const MTVAL: usize = 0x343;
26pub const MIP: usize = 0x344;
27pub const MSECCFG: usize = 0x747;
28pub const MSECCFGH: usize = 0x757;
29pub const PMPCFG0: usize = 0x3A0;
30pub const PMPCFG1: usize = 0x3A1;
31pub const PMPCFG2: usize = 0x3A2;
32pub const PMPCFG3: usize = 0x3A3;
33pub const PMPCFG4: usize = 0x3A4;
34pub const PMPCFG5: usize = 0x3A5;
35pub const PMPCFG6: usize = 0x3A6;
36pub const PMPCFG7: usize = 0x3A7;
37pub const PMPCFG8: usize = 0x3A8;
38pub const PMPCFG9: usize = 0x3A9;
39pub const PMPCFG10: usize = 0x3AA;
40pub const PMPCFG11: usize = 0x3AB;
41pub const PMPCFG12: usize = 0x3AC;
42pub const PMPCFG13: usize = 0x3AD;
43pub const PMPCFG14: usize = 0x3AE;
44pub const PMPCFG15: usize = 0x3AF;
45pub const PMPADDR0: usize = 0x3B0;
46pub const PMPADDR1: usize = 0x3B1;
47pub const PMPADDR2: usize = 0x3B2;
48pub const PMPADDR3: usize = 0x3B3;
49pub const PMPADDR4: usize = 0x3B4;
50pub const PMPADDR5: usize = 0x3B5;
51pub const PMPADDR6: usize = 0x3B6;
52pub const PMPADDR7: usize = 0x3B7;
53pub const PMPADDR8: usize = 0x3B8;
54pub const PMPADDR9: usize = 0x3B9;
55pub const PMPADDR10: usize = 0x3BA;
56pub const PMPADDR11: usize = 0x3BB;
57pub const PMPADDR12: usize = 0x3BC;
58pub const PMPADDR13: usize = 0x3BD;
59pub const PMPADDR14: usize = 0x3BE;
60pub const PMPADDR15: usize = 0x3BF;
61pub const PMPADDR16: usize = 0x3C0;
62pub const PMPADDR17: usize = 0x3C1;
63pub const PMPADDR18: usize = 0x3C2;
64pub const PMPADDR19: usize = 0x3C3;
65pub const PMPADDR20: usize = 0x3C4;
66pub const PMPADDR21: usize = 0x3C5;
67pub const PMPADDR22: usize = 0x3C6;
68pub const PMPADDR23: usize = 0x3C7;
69pub const PMPADDR24: usize = 0x3C8;
70pub const PMPADDR25: usize = 0x3C9;
71pub const PMPADDR26: usize = 0x3CA;
72pub const PMPADDR27: usize = 0x3CB;
73pub const PMPADDR28: usize = 0x3CC;
74pub const PMPADDR29: usize = 0x3CD;
75pub const PMPADDR30: usize = 0x3CE;
76pub const PMPADDR31: usize = 0x3CF;
77pub const PMPADDR32: usize = 0x3D0;
78pub const PMPADDR33: usize = 0x3D1;
79pub const PMPADDR34: usize = 0x3D2;
80pub const PMPADDR35: usize = 0x3D3;
81pub const PMPADDR36: usize = 0x3D4;
82pub const PMPADDR37: usize = 0x3D5;
83pub const PMPADDR38: usize = 0x3D6;
84pub const PMPADDR39: usize = 0x3D7;
85pub const PMPADDR40: usize = 0x3D8;
86pub const PMPADDR41: usize = 0x3D9;
87pub const PMPADDR42: usize = 0x3DA;
88pub const PMPADDR43: usize = 0x3DB;
89pub const PMPADDR44: usize = 0x3DC;
90pub const PMPADDR45: usize = 0x3DD;
91pub const PMPADDR46: usize = 0x3DE;
92pub const PMPADDR47: usize = 0x3DF;
93pub const PMPADDR48: usize = 0x3E0;
94pub const PMPADDR49: usize = 0x3E1;
95pub const PMPADDR50: usize = 0x3E2;
96pub const PMPADDR51: usize = 0x3E3;
97pub const PMPADDR52: usize = 0x3E4;
98pub const PMPADDR53: usize = 0x3E5;
99pub const PMPADDR54: usize = 0x3E6;
100pub const PMPADDR55: usize = 0x3E7;
101pub const PMPADDR56: usize = 0x3E8;
102pub const PMPADDR57: usize = 0x3E9;
103pub const PMPADDR58: usize = 0x3EA;
104pub const PMPADDR59: usize = 0x3EB;
105pub const PMPADDR60: usize = 0x3EC;
106pub const PMPADDR61: usize = 0x3ED;
107pub const PMPADDR62: usize = 0x3EE;
108pub const PMPADDR63: usize = 0x3EF;
109
110#[derive(Copy, Clone)]
112pub struct ReadWriteRiscvCsr<T: UIntLike, R: RegisterLongName, const V: usize> {
113 associated_register: PhantomData<R>,
114 associated_length: PhantomData<T>,
115}
116
117impl<R: RegisterLongName, const V: usize> ReadWriteRiscvCsr<usize, R, V> {
127 pub const fn new() -> Self {
128 ReadWriteRiscvCsr {
129 associated_register: PhantomData,
130 associated_length: PhantomData,
131 }
132 }
133
134 #[cfg(any(
148 doc,
149 all(
150 any(target_arch = "riscv32", target_arch = "riscv64"),
151 target_os = "none"
152 )
153 ))]
154 #[inline]
155 pub fn atomic_replace(&self, val_to_set: usize) -> usize {
156 use core::arch::asm;
157 let r: usize;
158 unsafe {
159 asm!(
160 "
161 csrrw {rd}, {csr}, {rs1}
162 ",
163 rd = out(reg) r,
164 csr = const V,
165 rs1 = in(reg) val_to_set,
166 );
167 }
168 r
169 }
170
171 #[cfg(not(any(
182 doc,
183 all(
184 any(target_arch = "riscv32", target_arch = "riscv64"),
185 target_os = "none"
186 )
187 )))]
188 pub fn atomic_replace(&self, _value_to_set: usize) -> usize {
189 unimplemented!("RISC-V CSR {} Atomic Read/Write", V)
190 }
191
192 #[cfg(any(
198 doc,
199 all(
200 any(target_arch = "riscv32", target_arch = "riscv64"),
201 target_os = "none"
202 )
203 ))]
204 #[inline]
205 pub fn read_and_set_bits(&self, bitmask: usize) -> usize {
206 use core::arch::asm;
207 let r: usize;
208 unsafe {
209 asm!(
210 "
211 csrrs {rd}, {csr}, {rs1}
212 ",
213 rd = out(reg) r,
214 csr = const V,
215 rs1 = in(reg) bitmask
216 );
217 }
218 r
219 }
220
221 #[cfg(not(any(
228 doc,
229 all(
230 any(target_arch = "riscv32", target_arch = "riscv64"),
231 target_os = "none"
232 )
233 )))]
234 pub fn read_and_set_bits(&self, bitmask: usize) -> usize {
235 unimplemented!(
236 "RISC-V CSR {} Atomic Read and Set Bits, bitmask {:04x}",
237 V,
238 bitmask
239 )
240 }
241
242 #[cfg(any(
248 doc,
249 all(
250 any(target_arch = "riscv32", target_arch = "riscv64"),
251 target_os = "none"
252 )
253 ))]
254 #[inline]
255 pub fn read_and_clear_bits(&self, bitmask: usize) -> usize {
256 use core::arch::asm;
257 let r: usize;
258 unsafe {
259 asm!(
260 "
261 csrrc {rd}, {csr}, {rs1}
262 ",
263 rd = out(reg) r,
264 csr = const V,
265 rs1 = in(reg) bitmask,
266 );
267 }
268 r
269 }
270
271 #[cfg(not(any(
278 doc,
279 all(
280 any(target_arch = "riscv32", target_arch = "riscv64"),
281 target_os = "none"
282 )
283 )))]
284 pub fn read_and_clear_bits(&self, bitmask: usize) -> usize {
285 unimplemented!(
286 "RISC-V CSR {} Atomic Read and Clear Bits, bitmask {:04x}",
287 V,
288 bitmask
289 )
290 }
291
292 #[inline]
300 pub fn read_and_set_field(&self, field: Field<usize, R>) -> usize {
301 field.read(self.read_and_set_bits(field.mask << field.shift))
302 }
303
304 #[inline]
312 pub fn read_and_clear_field(&self, field: Field<usize, R>) -> usize {
313 field.read(self.read_and_clear_bits(field.mask << field.shift))
314 }
315}
316
317impl<R: RegisterLongName, const V: usize> Readable for ReadWriteRiscvCsr<usize, R, V> {
318 type T = usize;
319 type R = R;
320
321 #[cfg(any(
322 doc,
323 all(
324 any(target_arch = "riscv32", target_arch = "riscv64"),
325 target_os = "none"
326 )
327 ))]
328 #[inline]
329 fn get(&self) -> usize {
330 use core::arch::asm;
331 let r: usize;
332 unsafe {
333 asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = const V);
334 }
335 r
336 }
337
338 #[cfg(not(any(
340 doc,
341 all(
342 any(target_arch = "riscv32", target_arch = "riscv64"),
343 target_os = "none"
344 )
345 )))]
346 fn get(&self) -> usize {
347 unimplemented!("reading RISC-V CSR {}", V)
348 }
349}
350
351impl<R: RegisterLongName, const V: usize> Writeable for ReadWriteRiscvCsr<usize, R, V> {
352 type T = usize;
353 type R = R;
354
355 #[cfg(any(
356 doc,
357 all(
358 any(target_arch = "riscv32", target_arch = "riscv64"),
359 target_os = "none"
360 )
361 ))]
362 #[inline]
363 fn set(&self, val_to_set: usize) {
364 use core::arch::asm;
365 unsafe {
366 asm!("csrw {csr}, {rs}", rs = in(reg) val_to_set, csr = const V);
367 }
368 }
369
370 #[cfg(not(any(
371 doc,
372 all(
373 any(target_arch = "riscv32", target_arch = "riscv64"),
374 target_os = "none"
375 )
376 )))]
377 fn set(&self, _val_to_set: usize) {
378 unimplemented!("writing RISC-V CSR {}", V)
379 }
380}