1#![no_std]
10#![no_main]
11
12use core::ptr::{addr_of, addr_of_mut};
13
14use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
15use e310_g003::interrupt_service::E310G003DefaultPeripherals;
16use kernel::capabilities;
17use kernel::component::Component;
18use kernel::hil;
19use kernel::platform::scheduler_timer::VirtualSchedulerTimer;
20use kernel::platform::{KernelResources, SyscallDriverLookup};
21use kernel::scheduler::cooperative::CooperativeSched;
22use kernel::utilities::registers::interfaces::ReadWriteable;
23use kernel::{create_capability, debug, static_init};
24use rv32i::csr;
25
26pub mod io;
27
28pub const NUM_PROCS: usize = 4;
29static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
33 [None; NUM_PROCS];
34
35static mut CHIP: Option<&'static e310_g003::chip::E310x<E310G003DefaultPeripherals>> = None;
37static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
39 None;
40
41const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
43 capsules_system::process_policies::PanicFaultPolicy {};
44
45#[no_mangle]
47#[link_section = ".stack_buffer"]
48pub static mut STACK_MEMORY: [u8; 0x1500] = [0; 0x1500];
49
50struct HiFiveInventor {
53 console: &'static capsules_core::console::Console<'static>,
54 lldb: &'static capsules_core::low_level_debug::LowLevelDebug<
55 'static,
56 capsules_core::virtualizers::virtual_uart::UartDevice<'static>,
57 >,
58 alarm: &'static capsules_core::alarm::AlarmDriver<
59 'static,
60 VirtualMuxAlarm<'static, e310_g003::chip::E310xClint<'static>>,
61 >,
62 scheduler: &'static CooperativeSched<'static>,
63 scheduler_timer: &'static VirtualSchedulerTimer<
64 VirtualMuxAlarm<'static, e310_g003::chip::E310xClint<'static>>,
65 >,
66}
67
68impl SyscallDriverLookup for HiFiveInventor {
70 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
71 where
72 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
73 {
74 match driver_num {
75 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
76 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
77 capsules_core::low_level_debug::DRIVER_NUM => f(Some(self.lldb)),
78 _ => f(None),
79 }
80 }
81}
82
83impl KernelResources<e310_g003::chip::E310x<'static, E310G003DefaultPeripherals<'static>>>
84 for HiFiveInventor
85{
86 type SyscallDriverLookup = Self;
87 type SyscallFilter = ();
88 type ProcessFault = ();
89 type Scheduler = CooperativeSched<'static>;
90 type SchedulerTimer =
91 VirtualSchedulerTimer<VirtualMuxAlarm<'static, e310_g003::chip::E310xClint<'static>>>;
92 type WatchDog = ();
93 type ContextSwitchCallback = ();
94
95 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
96 self
97 }
98 fn syscall_filter(&self) -> &Self::SyscallFilter {
99 &()
100 }
101 fn process_fault(&self) -> &Self::ProcessFault {
102 &()
103 }
104 fn scheduler(&self) -> &Self::Scheduler {
105 self.scheduler
106 }
107 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
108 self.scheduler_timer
109 }
110 fn watchdog(&self) -> &Self::WatchDog {
111 &()
112 }
113 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
114 &()
115 }
116}
117
118#[inline(never)]
122unsafe fn start() -> (
123 &'static kernel::Kernel,
124 HiFiveInventor,
125 &'static e310_g003::chip::E310x<'static, E310G003DefaultPeripherals<'static>>,
126) {
127 rv32i::configure_trap_handler();
129
130 let peripherals = static_init!(
131 E310G003DefaultPeripherals,
132 E310G003DefaultPeripherals::new(16_000_000)
133 );
134
135 peripherals.init();
137
138 peripherals
139 .e310x
140 .prci
141 .set_clock_frequency(sifive::prci::ClockFrequency::Freq16Mhz);
142
143 peripherals.e310x.uart0.initialize_gpio_pins(
144 &peripherals.e310x.gpio_port[17],
145 &peripherals.e310x.gpio_port[16],
146 );
147 peripherals.e310x.uart1.initialize_gpio_pins(
148 &peripherals.e310x.gpio_port[18],
149 &peripherals.e310x.gpio_port[23],
150 );
151
152 peripherals.e310x.watchdog.disable();
153 peripherals.e310x.rtc.disable();
154 peripherals.e310x.pwm0.disable();
155 peripherals.e310x.pwm1.disable();
156 peripherals.e310x.pwm2.disable();
157 peripherals.e310x.uart1.disable();
158
159 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
161 let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);
162
163 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
164
165 kernel::debug::assign_gpios(None, None, None);
167
168 let uart_mux = components::console::UartMuxComponent::new(&peripherals.e310x.uart0, 115200)
170 .finalize(components::uart_mux_component_static!());
171
172 let hardware_timer = static_init!(
173 e310_g003::chip::E310xClint,
174 e310_g003::chip::E310xClint::new(&e310_g003::clint::CLINT_BASE)
175 );
176
177 let mux_alarm = static_init!(
180 MuxAlarm<'static, e310_g003::chip::E310xClint>,
181 MuxAlarm::new(hardware_timer)
182 );
183 hil::time::Alarm::set_alarm_client(hardware_timer, mux_alarm);
184
185 let virtual_alarm_user = static_init!(
187 VirtualMuxAlarm<'static, e310_g003::chip::E310xClint>,
188 VirtualMuxAlarm::new(mux_alarm)
189 );
190 virtual_alarm_user.setup();
191
192 let systick_virtual_alarm = static_init!(
193 VirtualMuxAlarm<'static, e310_g003::chip::E310xClint>,
194 VirtualMuxAlarm::new(mux_alarm)
195 );
196 systick_virtual_alarm.setup();
197
198 let alarm = static_init!(
199 capsules_core::alarm::AlarmDriver<
200 'static,
201 VirtualMuxAlarm<'static, e310_g003::chip::E310xClint>,
202 >,
203 capsules_core::alarm::AlarmDriver::new(
204 virtual_alarm_user,
205 board_kernel.create_grant(capsules_core::alarm::DRIVER_NUM, &memory_allocation_cap)
206 )
207 );
208 hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm);
209
210 let chip = static_init!(
211 e310_g003::chip::E310x<E310G003DefaultPeripherals>,
212 e310_g003::chip::E310x::new(peripherals, hardware_timer)
213 );
214 CHIP = Some(chip);
215
216 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
217 .finalize(components::process_printer_text_component_static!());
218 PROCESS_PRINTER = Some(process_printer);
219
220 let process_console = components::process_console::ProcessConsoleComponent::new(
221 board_kernel,
222 uart_mux,
223 mux_alarm,
224 process_printer,
225 None,
226 )
227 .finalize(components::process_console_component_static!(
228 e310_g003::chip::E310xClint
229 ));
230 let _ = process_console.start();
231
232 chip.enable_plic_interrupts();
234
235 csr::CSR
237 .mie
238 .modify(csr::mie::mie::mext::SET + csr::mie::mie::msoft::SET + csr::mie::mie::mtimer::SET);
239 csr::CSR.mstatus.modify(csr::mstatus::mstatus::mie::SET);
240
241 let console = components::console::ConsoleComponent::new(
243 board_kernel,
244 capsules_core::console::DRIVER_NUM,
245 uart_mux,
246 )
247 .finalize(components::console_component_static!());
248 components::debug_writer::DebugWriterComponent::new(
250 uart_mux,
251 create_capability!(capabilities::SetDebugWriterCapability),
252 )
253 .finalize(components::debug_writer_component_static!());
254
255 let lldb = components::lldb::LowLevelDebugComponent::new(
256 board_kernel,
257 capsules_core::low_level_debug::DRIVER_NUM,
258 uart_mux,
259 )
260 .finalize(components::low_level_debug_component_static!());
261
262 debug!("HiFive1 initialization complete. Entering main loop.");
263
264 extern "C" {
266 static _sapps: u8;
268 static _eapps: u8;
270 static mut _sappmem: u8;
272 static _eappmem: u8;
274 }
275
276 let scheduler =
277 components::sched::cooperative::CooperativeComponent::new(&*addr_of!(PROCESSES))
278 .finalize(components::cooperative_component_static!(NUM_PROCS));
279
280 let scheduler_timer = static_init!(
281 VirtualSchedulerTimer<VirtualMuxAlarm<'static, e310_g003::chip::E310xClint<'static>>>,
282 VirtualSchedulerTimer::new(systick_virtual_alarm)
283 );
284 let hifive1 = HiFiveInventor {
285 console,
286 lldb,
287 alarm,
288 scheduler,
289 scheduler_timer,
290 };
291 kernel::process::load_processes(
292 board_kernel,
293 chip,
294 core::slice::from_raw_parts(
295 core::ptr::addr_of!(_sapps),
296 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
297 ),
298 core::slice::from_raw_parts_mut(
299 core::ptr::addr_of_mut!(_sappmem),
300 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
301 ),
302 &mut *addr_of_mut!(PROCESSES),
303 &FAULT_RESPONSE,
304 &process_mgmt_cap,
305 )
306 .unwrap_or_else(|err| {
307 debug!("Error loading processes!");
308 debug!("{:?}", err);
309 });
310
311 (board_kernel, hifive1, chip)
312}
313
314#[no_mangle]
316pub unsafe fn main() {
317 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
318
319 let (board_kernel, board, chip) = start();
320 board_kernel.kernel_loop(
321 &board,
322 chip,
323 None::<&kernel::ipc::IPC<0>>,
324 &main_loop_capability,
325 );
326}