andes_riscv/
plic.rs

1#![allow(clippy::missing_safety_doc)]
2#![allow(clippy::identity_op)]
3#![allow(clippy::unnecessary_cast)]
4#![allow(clippy::erasing_op)]
5
6#[doc = "PLIC."]
7#[derive(Copy, Clone, Eq, PartialEq)]
8pub struct Plic {
9    ptr: *mut u8,
10}
11unsafe impl Send for Plic {}
12unsafe impl Sync for Plic {}
13impl Plic {
14    #[inline(always)]
15    pub const unsafe fn from_ptr(ptr: *mut ()) -> Self {
16        Self { ptr: ptr as _ }
17    }
18    #[inline(always)]
19    pub const fn as_ptr(&self) -> *mut () {
20        self.ptr as _
21    }
22    #[doc = "Feature enable register."]
23    #[inline(always)]
24    pub const fn feature(self) -> self::common::Reg<regs::Feature, self::common::RW> {
25        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x0usize) as _) }
26    }
27    #[doc = "no description available."]
28    #[inline(always)]
29    pub const fn priority(self, n: usize) -> self::common::Reg<regs::Priority, self::common::RW> {
30        assert!(n < 127usize);
31        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x04usize + n * 4usize) as _) }
32    }
33    #[doc = "no description available."]
34    #[inline(always)]
35    pub const fn pending(self, n: usize) -> self::common::Reg<regs::Pending, self::common::RW> {
36        assert!(n < 4usize);
37        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x1000usize + n * 4usize) as _) }
38    }
39    #[doc = "no description available."]
40    #[inline(always)]
41    pub const fn trigger(self, n: usize) -> self::common::Reg<regs::Trigger, self::common::RW> {
42        assert!(n < 4usize);
43        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x1080usize + n * 4usize) as _) }
44    }
45    #[doc = "Number of supported interrupt sources and targets."]
46    #[inline(always)]
47    pub const fn number(self) -> self::common::Reg<regs::Number, self::common::RW> {
48        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x1100usize) as _) }
49    }
50    #[doc = "Version and the maximum priority."]
51    #[inline(always)]
52    pub const fn info(self) -> self::common::Reg<regs::Info, self::common::RW> {
53        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x1104usize) as _) }
54    }
55    #[doc = "no description available."]
56    #[inline(always)]
57    pub const fn targetint(self, n: usize) -> Targetint {
58        assert!(n < 2usize);
59        unsafe { Targetint::from_ptr(self.ptr.add(0x2000usize + n * 128usize) as _) }
60    }
61    #[doc = "no description available."]
62    #[inline(always)]
63    pub const fn targetconfig(self, n: usize) -> Targetconfig {
64        assert!(n < 2usize);
65        unsafe { Targetconfig::from_ptr(self.ptr.add(0x0020_0000usize + n * 4096usize) as _) }
66    }
67}
68
69#[doc = "PLICSW, Platform Level Software Interrupt Controller. Compatible with PLIC."]
70#[derive(Copy, Clone, Eq, PartialEq)]
71pub struct Plicsw {
72    ptr: *mut u8,
73}
74unsafe impl Send for Plicsw {}
75unsafe impl Sync for Plicsw {}
76impl Plicsw {
77    #[inline(always)]
78    pub const unsafe fn from_ptr(ptr: *mut ()) -> Self {
79        Self { ptr: ptr as _ }
80    }
81    #[inline(always)]
82    pub const fn as_ptr(&self) -> *mut () {
83        self.ptr as _
84    }
85    #[doc = "Pending status."]
86    #[inline(always)]
87    pub const fn pending(self) -> self::common::Reg<regs::Pending, self::common::RW> {
88        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x1000usize) as _) }
89    }
90    #[doc = "Interrupt enable."]
91    #[inline(always)]
92    pub const fn inten(self) -> self::common::Reg<regs::Inten, self::common::RW> {
93        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x2000usize) as _) }
94    }
95    #[doc = "Claim and complete."]
96    #[inline(always)]
97    pub const fn claim(self) -> self::common::Reg<regs::Claim, self::common::RW> {
98        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x0020_0004usize) as _) }
99    }
100}
101
102#[doc = "no description available."]
103#[derive(Copy, Clone, Eq, PartialEq)]
104pub struct Targetconfig {
105    ptr: *mut u8,
106}
107unsafe impl Send for Targetconfig {}
108unsafe impl Sync for Targetconfig {}
109impl Targetconfig {
110    #[inline(always)]
111    pub const unsafe fn from_ptr(ptr: *mut ()) -> Self {
112        Self { ptr: ptr as _ }
113    }
114    #[inline(always)]
115    pub const fn as_ptr(&self) -> *mut () {
116        self.ptr as _
117    }
118    #[doc = "Target0 priority threshold."]
119    #[inline(always)]
120    pub const fn threshold(self) -> self::common::Reg<regs::Threshold, self::common::RW> {
121        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x0usize) as _) }
122    }
123    #[doc = "Target claim and complete."]
124    #[inline(always)]
125    pub const fn claim(self) -> self::common::Reg<regs::Claim, self::common::RW> {
126        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x04usize) as _) }
127    }
128    #[doc = "Preempted priority stack."]
129    #[inline(always)]
130    pub const fn pps(self) -> self::common::Reg<regs::Pps, self::common::RW> {
131        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x0400usize) as _) }
132    }
133}
134#[doc = "no description available."]
135#[derive(Copy, Clone, Eq, PartialEq)]
136pub struct Targetint {
137    ptr: *mut u8,
138}
139unsafe impl Send for Targetint {}
140unsafe impl Sync for Targetint {}
141impl Targetint {
142    #[inline(always)]
143    pub const unsafe fn from_ptr(ptr: *mut ()) -> Self {
144        Self { ptr: ptr as _ }
145    }
146    #[inline(always)]
147    pub const fn as_ptr(&self) -> *mut () {
148        self.ptr as _
149    }
150    #[doc = "no description available."]
151    #[inline(always)]
152    pub const fn inten(self, n: usize) -> self::common::Reg<regs::Inten, self::common::RW> {
153        assert!(n < 4usize);
154        unsafe { self::common::Reg::from_ptr(self.ptr.add(0x0usize + n * 4usize) as _) }
155    }
156}
157pub mod common {
158    use core::marker::PhantomData;
159    #[derive(Copy, Clone, PartialEq, Eq)]
160    pub struct RW;
161    #[derive(Copy, Clone, PartialEq, Eq)]
162    pub struct R;
163    #[derive(Copy, Clone, PartialEq, Eq)]
164    pub struct W;
165    mod sealed {
166        use super::*;
167        pub trait Access {}
168        impl Access for R {}
169        impl Access for W {}
170        impl Access for RW {}
171    }
172    pub trait Access: sealed::Access + Copy {}
173    impl Access for R {}
174    impl Access for W {}
175    impl Access for RW {}
176    pub trait Read: Access {}
177    impl Read for RW {}
178    impl Read for R {}
179    pub trait Write: Access {}
180    impl Write for RW {}
181    impl Write for W {}
182    #[derive(Copy, Clone, PartialEq, Eq)]
183    pub struct Reg<T: Copy, A: Access> {
184        ptr: *mut u8,
185        phantom: PhantomData<*mut (T, A)>,
186    }
187    unsafe impl<T: Copy, A: Access> Send for Reg<T, A> {}
188    unsafe impl<T: Copy, A: Access> Sync for Reg<T, A> {}
189    impl<T: Copy, A: Access> Reg<T, A> {
190        #[allow(clippy::missing_safety_doc)]
191        #[inline(always)]
192        pub const unsafe fn from_ptr(ptr: *mut T) -> Self {
193            Self {
194                ptr: ptr as _,
195                phantom: PhantomData,
196            }
197        }
198        #[inline(always)]
199        pub const fn as_ptr(&self) -> *mut T {
200            self.ptr as _
201        }
202    }
203    impl<T: Copy, A: Read> Reg<T, A> {
204        #[inline(always)]
205        pub fn read(&self) -> T {
206            unsafe { (self.ptr as *mut T).read_volatile() }
207        }
208    }
209    impl<T: Copy, A: Write> Reg<T, A> {
210        #[inline(always)]
211        pub fn write_value(&self, val: T) {
212            unsafe { (self.ptr as *mut T).write_volatile(val) }
213        }
214    }
215    impl<T: Default + Copy, A: Write> Reg<T, A> {
216        #[inline(always)]
217        pub fn write<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
218            let mut val = Default::default();
219            let res = f(&mut val);
220            self.write_value(val);
221            res
222        }
223    }
224    impl<T: Copy, A: Read + Write> Reg<T, A> {
225        #[inline(always)]
226        pub fn modify<R>(&self, f: impl FnOnce(&mut T) -> R) -> R {
227            let mut val = self.read();
228            let res = f(&mut val);
229            self.write_value(val);
230            res
231        }
232    }
233}
234pub mod regs {
235    #[doc = "Target claim and complete."]
236    #[repr(transparent)]
237    #[derive(Copy, Clone, Eq, PartialEq)]
238    pub struct Claim(pub u32);
239    impl Claim {
240        #[doc = "On reads, indicating the interrupt source that has being claimed. On writes, indicating the interrupt source that has been handled (completed)."]
241        #[inline(always)]
242        pub const fn interrupt_id(&self) -> u16 {
243            let val = (self.0 >> 0usize) & 0x03ff;
244            val as u16
245        }
246        #[doc = "On reads, indicating the interrupt source that has being claimed. On writes, indicating the interrupt source that has been handled (completed)."]
247        #[inline(always)]
248        pub fn set_interrupt_id(&mut self, val: u16) {
249            self.0 = (self.0 & !(0x03ff << 0usize)) | (((val as u32) & 0x03ff) << 0usize);
250        }
251    }
252    impl Default for Claim {
253        #[inline(always)]
254        fn default() -> Claim {
255            Claim(0)
256        }
257    }
258    #[doc = "Feature enable register."]
259    #[repr(transparent)]
260    #[derive(Copy, Clone, Eq, PartialEq)]
261    pub struct Feature(pub u32);
262    impl Feature {
263        #[doc = "Preemptive priority interrupt enable 0: Disabled 1: Enabled."]
264        #[inline(always)]
265        pub const fn preempt(&self) -> bool {
266            let val = (self.0 >> 0usize) & 0x01;
267            val != 0
268        }
269        #[doc = "Preemptive priority interrupt enable 0: Disabled 1: Enabled."]
270        #[inline(always)]
271        pub fn set_preempt(&mut self, val: bool) {
272            self.0 = (self.0 & !(0x01 << 0usize)) | (((val as u32) & 0x01) << 0usize);
273        }
274        #[doc = "Vector mode enable 0: Disabled 1: Enabled."]
275        #[inline(always)]
276        pub const fn vectored(&self) -> bool {
277            let val = (self.0 >> 1usize) & 0x01;
278            val != 0
279        }
280        #[doc = "Vector mode enable 0: Disabled 1: Enabled."]
281        #[inline(always)]
282        pub fn set_vectored(&mut self, val: bool) {
283            self.0 = (self.0 & !(0x01 << 1usize)) | (((val as u32) & 0x01) << 1usize);
284        }
285    }
286    impl Default for Feature {
287        #[inline(always)]
288        fn default() -> Feature {
289            Feature(0)
290        }
291    }
292    #[doc = "Version and the maximum priority."]
293    #[repr(transparent)]
294    #[derive(Copy, Clone, Eq, PartialEq)]
295    pub struct Info(pub u32);
296    impl Info {
297        #[doc = "The version of the PLIC design."]
298        #[inline(always)]
299        pub const fn version(&self) -> u16 {
300            let val = (self.0 >> 0usize) & 0xffff;
301            val as u16
302        }
303        #[doc = "The version of the PLIC design."]
304        #[inline(always)]
305        pub fn set_version(&mut self, val: u16) {
306            self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize);
307        }
308        #[doc = "The maximum priority supported."]
309        #[inline(always)]
310        pub const fn max_priority(&self) -> u16 {
311            let val = (self.0 >> 16usize) & 0xffff;
312            val as u16
313        }
314        #[doc = "The maximum priority supported."]
315        #[inline(always)]
316        pub fn set_max_priority(&mut self, val: u16) {
317            self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize);
318        }
319    }
320    impl Default for Info {
321        #[inline(always)]
322        fn default() -> Info {
323            Info(0)
324        }
325    }
326    #[doc = "no description available."]
327    #[repr(transparent)]
328    #[derive(Copy, Clone, Eq, PartialEq)]
329    pub struct Inten(pub u32);
330    impl Inten {
331        #[doc = "The interrupt enable bit for interrupt. Every interrupt source occupies 1 bit."]
332        #[inline(always)]
333        pub const fn interrupt(&self) -> u32 {
334            let val = (self.0 >> 0usize) & 0xffff_ffff;
335            val as u32
336        }
337        #[doc = "The interrupt enable bit for interrupt. Every interrupt source occupies 1 bit."]
338        #[inline(always)]
339        pub fn set_interrupt(&mut self, val: u32) {
340            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
341        }
342    }
343    impl Default for Inten {
344        #[inline(always)]
345        fn default() -> Inten {
346            Inten(0)
347        }
348    }
349    #[doc = "Number of supported interrupt sources and targets."]
350    #[repr(transparent)]
351    #[derive(Copy, Clone, Eq, PartialEq)]
352    pub struct Number(pub u32);
353    impl Number {
354        #[doc = "The number of supported interrupt sources."]
355        #[inline(always)]
356        pub const fn num_interrupt(&self) -> u16 {
357            let val = (self.0 >> 0usize) & 0xffff;
358            val as u16
359        }
360        #[doc = "The number of supported interrupt sources."]
361        #[inline(always)]
362        pub fn set_num_interrupt(&mut self, val: u16) {
363            self.0 = (self.0 & !(0xffff << 0usize)) | (((val as u32) & 0xffff) << 0usize);
364        }
365        #[doc = "The number of supported targets."]
366        #[inline(always)]
367        pub const fn num_target(&self) -> u16 {
368            let val = (self.0 >> 16usize) & 0xffff;
369            val as u16
370        }
371        #[doc = "The number of supported targets."]
372        #[inline(always)]
373        pub fn set_num_target(&mut self, val: u16) {
374            self.0 = (self.0 & !(0xffff << 16usize)) | (((val as u32) & 0xffff) << 16usize);
375        }
376    }
377    impl Default for Number {
378        #[inline(always)]
379        fn default() -> Number {
380            Number(0)
381        }
382    }
383    #[doc = "no description available."]
384    #[repr(transparent)]
385    #[derive(Copy, Clone, Eq, PartialEq)]
386    pub struct Pending(pub u32);
387    impl Pending {
388        #[doc = "The interrupt pending status of inpterrupt sources. Every interrupt source occupies 1 bit."]
389        #[inline(always)]
390        pub const fn interrupt(&self) -> u32 {
391            let val = (self.0 >> 0usize) & 0xffff_ffff;
392            val as u32
393        }
394        #[doc = "The interrupt pending status of inpterrupt sources. Every interrupt source occupies 1 bit."]
395        #[inline(always)]
396        pub fn set_interrupt(&mut self, val: u32) {
397            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
398        }
399    }
400    impl Default for Pending {
401        #[inline(always)]
402        fn default() -> Pending {
403            Pending(0)
404        }
405    }
406    #[doc = "Preempted priority stack."]
407    #[repr(transparent)]
408    #[derive(Copy, Clone, Eq, PartialEq)]
409    pub struct Pps(pub u32);
410    impl Pps {
411        #[doc = "Each bit indicates if the corresponding priority level has been preempted by a higher-priority interrupt."]
412        #[inline(always)]
413        pub const fn priority_preempted(&self) -> u32 {
414            let val = (self.0 >> 0usize) & 0xffff_ffff;
415            val as u32
416        }
417        #[doc = "Each bit indicates if the corresponding priority level has been preempted by a higher-priority interrupt."]
418        #[inline(always)]
419        pub fn set_priority_preempted(&mut self, val: u32) {
420            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
421        }
422    }
423    impl Default for Pps {
424        #[inline(always)]
425        fn default() -> Pps {
426            Pps(0)
427        }
428    }
429    #[doc = "no description available."]
430    #[repr(transparent)]
431    #[derive(Copy, Clone, Eq, PartialEq)]
432    pub struct Priority(pub u32);
433    impl Priority {
434        #[doc = "Interrupt source priority. The valid range of this field is 0-7. 0: Never interrupt 1-7: Interrupt source priority. The larger the value, the higher the priority."]
435        #[inline(always)]
436        pub const fn priority(&self) -> u32 {
437            let val = (self.0 >> 0usize) & 0xffff_ffff;
438            val as u32
439        }
440        #[doc = "Interrupt source priority. The valid range of this field is 0-7. 0: Never interrupt 1-7: Interrupt source priority. The larger the value, the higher the priority."]
441        #[inline(always)]
442        pub fn set_priority(&mut self, val: u32) {
443            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
444        }
445    }
446    impl Default for Priority {
447        #[inline(always)]
448        fn default() -> Priority {
449            Priority(0)
450        }
451    }
452    #[doc = "Target0 priority threshold."]
453    #[repr(transparent)]
454    #[derive(Copy, Clone, Eq, PartialEq)]
455    pub struct Threshold(pub u32);
456    impl Threshold {
457        #[doc = "Interrupt priority threshold."]
458        #[inline(always)]
459        pub const fn threshold(&self) -> u32 {
460            let val = (self.0 >> 0usize) & 0xffff_ffff;
461            val as u32
462        }
463        #[doc = "Interrupt priority threshold."]
464        #[inline(always)]
465        pub fn set_threshold(&mut self, val: u32) {
466            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
467        }
468    }
469    impl Default for Threshold {
470        #[inline(always)]
471        fn default() -> Threshold {
472            Threshold(0)
473        }
474    }
475    #[doc = "no description available."]
476    #[repr(transparent)]
477    #[derive(Copy, Clone, Eq, PartialEq)]
478    pub struct Trigger(pub u32);
479    impl Trigger {
480        #[doc = "The interrupt trigger type of interrupt sources. Every interrupt source occupies 1 bit. 0: Level-triggered interrupt 1: Edge-triggered interrupt."]
481        #[inline(always)]
482        pub const fn interrupt(&self) -> u32 {
483            let val = (self.0 >> 0usize) & 0xffff_ffff;
484            val as u32
485        }
486        #[doc = "The interrupt trigger type of interrupt sources. Every interrupt source occupies 1 bit. 0: Level-triggered interrupt 1: Edge-triggered interrupt."]
487        #[inline(always)]
488        pub fn set_interrupt(&mut self, val: u32) {
489            self.0 = (self.0 & !(0xffff_ffff << 0usize)) | (((val as u32) & 0xffff_ffff) << 0usize);
490        }
491    }
492    impl Default for Trigger {
493        #[inline(always)]
494        fn default() -> Trigger {
495            Trigger(0)
496        }
497    }
498}
499
500// Helper extension trait for the PLIC
501pub trait PlicExt {
502    unsafe fn enable_vectored_mode(&self);
503
504    unsafe fn enable_preemptive_mode(&self);
505
506    fn threshold(&self) -> u32;
507
508    fn set_threshold(&self, threshold: u32);
509
510    fn claim(&self) -> u16;
511
512    fn complete(&self, id: u16);
513}
514
515impl PlicExt for Plic {
516    #[inline]
517    unsafe fn enable_vectored_mode(&self) {
518        self.feature().modify(|w| w.set_vectored(true));
519    }
520
521    #[inline]
522    unsafe fn enable_preemptive_mode(&self) {
523        self.feature().modify(|w| w.set_preempt(true));
524    }
525
526    #[inline]
527    fn threshold(&self) -> u32 {
528        self.targetconfig(0).threshold().read().threshold()
529    }
530
531    #[inline]
532    fn set_threshold(&self, threshold: u32) {
533        self.targetconfig(0)
534            .threshold()
535            .write(|w| w.set_threshold(threshold));
536    }
537
538    #[inline]
539    fn claim(&self) -> u16 {
540        self.targetconfig(0).claim().read().interrupt_id()
541    }
542
543    #[inline]
544    fn complete(&self, id: u16) {
545        self.targetconfig(0)
546            .claim()
547            .modify(|w| w.set_interrupt_id(id));
548    }
549}