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!("csrrw {rd}, {csr}, {rs1}",
160 rd = out(reg) r,
161 csr = const V,
162 rs1 = in(reg) val_to_set);
163 }
164 r
165 }
166
167 #[cfg(not(any(
178 doc,
179 all(
180 any(target_arch = "riscv32", target_arch = "riscv64"),
181 target_os = "none"
182 )
183 )))]
184 pub fn atomic_replace(&self, _value_to_set: usize) -> usize {
185 unimplemented!("RISC-V CSR {} Atomic Read/Write", V)
186 }
187
188 #[cfg(any(
194 doc,
195 all(
196 any(target_arch = "riscv32", target_arch = "riscv64"),
197 target_os = "none"
198 )
199 ))]
200 #[inline]
201 pub fn read_and_set_bits(&self, bitmask: usize) -> usize {
202 use core::arch::asm;
203 let r: usize;
204 unsafe {
205 asm!("csrrs {rd}, {csr}, {rs1}",
206 rd = out(reg) r,
207 csr = const V,
208 rs1 = in(reg) bitmask);
209 }
210 r
211 }
212
213 #[cfg(not(any(
220 doc,
221 all(
222 any(target_arch = "riscv32", target_arch = "riscv64"),
223 target_os = "none"
224 )
225 )))]
226 pub fn read_and_set_bits(&self, bitmask: usize) -> usize {
227 unimplemented!(
228 "RISC-V CSR {} Atomic Read and Set Bits, bitmask {:04x}",
229 V,
230 bitmask
231 )
232 }
233
234 #[cfg(any(
240 doc,
241 all(
242 any(target_arch = "riscv32", target_arch = "riscv64"),
243 target_os = "none"
244 )
245 ))]
246 #[inline]
247 pub fn read_and_clear_bits(&self, bitmask: usize) -> usize {
248 use core::arch::asm;
249 let r: usize;
250 unsafe {
251 asm!("csrrc {rd}, {csr}, {rs1}",
252 rd = out(reg) r,
253 csr = const V,
254 rs1 = in(reg) bitmask);
255 }
256 r
257 }
258
259 #[cfg(not(any(
266 doc,
267 all(
268 any(target_arch = "riscv32", target_arch = "riscv64"),
269 target_os = "none"
270 )
271 )))]
272 pub fn read_and_clear_bits(&self, bitmask: usize) -> usize {
273 unimplemented!(
274 "RISC-V CSR {} Atomic Read and Clear Bits, bitmask {:04x}",
275 V,
276 bitmask
277 )
278 }
279
280 #[inline]
288 pub fn read_and_set_field(&self, field: Field<usize, R>) -> usize {
289 field.read(self.read_and_set_bits(field.mask << field.shift))
290 }
291
292 #[inline]
300 pub fn read_and_clear_field(&self, field: Field<usize, R>) -> usize {
301 field.read(self.read_and_clear_bits(field.mask << field.shift))
302 }
303}
304
305impl<R: RegisterLongName, const V: usize> Readable for ReadWriteRiscvCsr<usize, R, V> {
306 type T = usize;
307 type R = R;
308
309 #[cfg(any(
310 doc,
311 all(
312 any(target_arch = "riscv32", target_arch = "riscv64"),
313 target_os = "none"
314 )
315 ))]
316 #[inline]
317 fn get(&self) -> usize {
318 use core::arch::asm;
319 let r: usize;
320 unsafe {
321 asm!("csrr {rd}, {csr}", rd = out(reg) r, csr = const V);
322 }
323 r
324 }
325
326 #[cfg(not(any(
328 doc,
329 all(
330 any(target_arch = "riscv32", target_arch = "riscv64"),
331 target_os = "none"
332 )
333 )))]
334 fn get(&self) -> usize {
335 unimplemented!("reading RISC-V CSR {}", V)
336 }
337}
338
339impl<R: RegisterLongName, const V: usize> Writeable for ReadWriteRiscvCsr<usize, R, V> {
340 type T = usize;
341 type R = R;
342
343 #[cfg(any(
344 doc,
345 all(
346 any(target_arch = "riscv32", target_arch = "riscv64"),
347 target_os = "none"
348 )
349 ))]
350 #[inline]
351 fn set(&self, val_to_set: usize) {
352 use core::arch::asm;
353 unsafe {
354 asm!("csrw {csr}, {rs}", rs = in(reg) val_to_set, csr = const V);
355 }
356 }
357
358 #[cfg(not(any(
359 doc,
360 all(
361 any(target_arch = "riscv32", target_arch = "riscv64"),
362 target_os = "none"
363 )
364 )))]
365 fn set(&self, _val_to_set: usize) {
366 unimplemented!("writing RISC-V CSR {}", V)
367 }
368}