1use core::fmt::Write;
8use kernel::platform::chip::Chip;
9use kernel::platform::chip::InterruptService;
10
11use crate::clocks::Clocks;
12use crate::gpio::{RPPins, SIO};
13use crate::interrupts;
14use crate::resets::Resets;
15use crate::ticks::Ticks;
16use crate::timer::RPTimer;
17use crate::uart::Uart;
18use crate::xosc::Xosc;
19use cortexm33::{interrupt_mask, CortexM33, CortexMVariant};
20
21#[repr(u8)]
22pub enum Processor {
23 Processor0 = 0,
24 Processor1 = 1,
25}
26
27pub struct Rp2350<'a, I: InterruptService + 'a> {
28 mpu: cortexm33::mpu::MPU<8>,
29 userspace_kernel_boundary: cortexm33::syscall::SysCall,
30 interrupt_service: &'a I,
31 sio: &'a SIO,
32 processor0_interrupt_mask: (u128, u128),
33 processor1_interrupt_mask: (u128, u128),
34}
35
36impl<'a, I: InterruptService> Rp2350<'a, I> {
37 pub unsafe fn new(interrupt_service: &'a I, sio: &'a SIO) -> Self {
38 Self {
39 mpu: cortexm33::mpu::new(),
40 userspace_kernel_boundary: cortexm33::syscall::SysCall::new(),
41 interrupt_service,
42 sio,
43 processor0_interrupt_mask: interrupt_mask!(interrupts::PROC1_IRQ_CTI),
44 processor1_interrupt_mask: interrupt_mask!(interrupts::PROC0_IRQ_CTI),
45 }
46 }
47}
48
49impl<I: InterruptService> Chip for Rp2350<'_, I> {
50 type MPU = cortexm33::mpu::MPU<8>;
51 type UserspaceKernelBoundary = cortexm33::syscall::SysCall;
52 type ThreadIdProvider = cortexm33::thread_id::CortexMThreadIdProvider;
53
54 fn service_pending_interrupts(&self) {
55 unsafe {
56 let mask = match self.sio.get_processor() {
57 Processor::Processor0 => self.processor0_interrupt_mask,
58 Processor::Processor1 => self.processor1_interrupt_mask,
59 };
60 while let Some(interrupt) = cortexm33::nvic::next_pending_with_mask(mask) {
61 if !self.interrupt_service.service_interrupt(interrupt) {
65 panic!("unhandled interrupt {}", interrupt);
66 }
67 let n = cortexm33::nvic::Nvic::new(interrupt);
68 n.clear_pending();
69 n.enable();
70 }
71 }
72 }
73
74 fn has_pending_interrupts(&self) -> bool {
75 let mask = match self.sio.get_processor() {
76 Processor::Processor0 => self.processor0_interrupt_mask,
77 Processor::Processor1 => self.processor1_interrupt_mask,
78 };
79 unsafe { cortexm33::nvic::has_pending_with_mask(mask) }
80 }
81
82 fn mpu(&self) -> &Self::MPU {
83 &self.mpu
84 }
85
86 fn userspace_kernel_boundary(&self) -> &Self::UserspaceKernelBoundary {
87 &self.userspace_kernel_boundary
88 }
89
90 fn sleep(&self) {
91 unsafe {
92 cortexm33::support::wfi();
93 }
94 }
95
96 unsafe fn with_interrupts_disabled<F, R>(&self, f: F) -> R
97 where
98 F: FnOnce() -> R,
99 {
100 cortexm33::support::with_interrupts_disabled(f)
101 }
102
103 unsafe fn print_state(&self, writer: &mut dyn Write) {
104 CortexM33::print_cortexm_state(writer);
105 }
106}
107
108pub struct Rp2350DefaultPeripherals<'a> {
109 pub clocks: Clocks,
110 pub pins: RPPins<'a>,
111 pub resets: Resets,
112 pub sio: SIO,
113 pub ticks: Ticks,
114 pub timer0: RPTimer<'a>,
115 pub uart0: Uart<'a>,
116 pub uart1: Uart<'a>,
117 pub xosc: Xosc,
118}
119
120impl Rp2350DefaultPeripherals<'_> {
121 pub fn new() -> Self {
122 Self {
123 clocks: Clocks::new(),
124 pins: RPPins::new(),
125 resets: Resets::new(),
126 sio: SIO::new(),
127 ticks: Ticks::new(),
128 timer0: RPTimer::new_timer0(),
129 uart0: Uart::new_uart0(),
130 uart1: Uart::new_uart1(),
131 xosc: Xosc::new(),
132 }
133 }
134
135 pub fn resolve_dependencies(&'static self) {
136 self.uart0.set_clocks(&self.clocks);
137 self.ticks.set_timer0_generator();
138 self.ticks.set_timer1_generator();
139 kernel::deferred_call::DeferredCallClient::register(&self.uart0);
140 kernel::deferred_call::DeferredCallClient::register(&self.uart1);
141 }
142}
143
144impl InterruptService for Rp2350DefaultPeripherals<'_> {
145 unsafe fn service_interrupt(&self, interrupt: u32) -> bool {
146 match interrupt {
147 interrupts::TIMER0_IRQ_0 => {
148 self.timer0.handle_interrupt();
149 true
150 }
151 interrupts::SIO_IRQ_FIFO => {
152 self.sio.handle_proc_interrupt(self.sio.get_processor());
153 true
154 }
155 interrupts::UART0_IRQ => {
156 self.uart0.handle_interrupt();
157 true
158 }
159 _ => false,
160 }
161 }
162}