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