1#![no_std]
9#![no_main]
10
11use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
12use kernel::capabilities;
13use kernel::component::Component;
14use kernel::debug::PanicResources;
15use kernel::hil;
16use kernel::platform::{KernelResources, SyscallDriverLookup};
17use kernel::scheduler::cooperative::CooperativeSched;
18use kernel::utilities::registers::interfaces::ReadWriteable;
19use kernel::utilities::single_thread_value::SingleThreadValue;
20use kernel::{create_capability, debug, static_init};
21use rv32i::csr;
22use veer_el2::chip::VeeRDefaultPeripherals;
23
24use veer_el2::machine_timer::Clint;
25use veer_el2::machine_timer::CLINT_BASE;
26
27pub mod io;
28
29pub const NUM_PROCS: usize = 4;
30
31pub type VeeRChip = veer_el2::chip::VeeR<'static, VeeRDefaultPeripherals>;
32pub type ChipHw = VeeRChip;
33type AlarmHw = Clint<'static>;
34type SchedulerTimerHw =
35 components::virtual_scheduler_timer::VirtualSchedulerTimerComponentType<AlarmHw>;
36type ProcessPrinterInUse = capsules_system::process_printer::ProcessPrinterText;
37
38static PANIC_RESOURCES: SingleThreadValue<PanicResources<ChipHw, ProcessPrinterInUse>> =
40 SingleThreadValue::new(PanicResources::new());
41
42const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
44 capsules_system::process_policies::PanicFaultPolicy {};
45
46kernel::stack_size! {0x900}
47
48struct VeeR {
51 console: &'static capsules_core::console::Console<'static>,
52 alarm: &'static capsules_core::alarm::AlarmDriver<
53 'static,
54 VirtualMuxAlarm<'static, Clint<'static>>,
55 >,
56 scheduler: &'static CooperativeSched<'static>,
57 scheduler_timer: &'static SchedulerTimerHw,
58}
59
60impl SyscallDriverLookup for VeeR {
62 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
63 where
64 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
65 {
66 match driver_num {
67 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
68 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
69 _ => f(None),
70 }
71 }
72}
73
74impl KernelResources<VeeRChip> for VeeR {
75 type SyscallDriverLookup = Self;
76 type SyscallFilter = ();
77 type ProcessFault = ();
78 type Scheduler = CooperativeSched<'static>;
79 type SchedulerTimer = SchedulerTimerHw;
80 type WatchDog = ();
81 type ContextSwitchCallback = ();
82
83 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
84 self
85 }
86 fn syscall_filter(&self) -> &Self::SyscallFilter {
87 &()
88 }
89 fn process_fault(&self) -> &Self::ProcessFault {
90 &()
91 }
92 fn scheduler(&self) -> &Self::Scheduler {
93 self.scheduler
94 }
95 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
96 self.scheduler_timer
97 }
98 fn watchdog(&self) -> &Self::WatchDog {
99 &()
100 }
101 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
102 &()
103 }
104}
105
106#[inline(never)]
110unsafe fn start() -> (&'static kernel::Kernel, VeeR, &'static VeeRChip) {
111 rv32i::configure_trap_handler();
113
114 kernel::deferred_call::initialize_deferred_call_state_unsafe::<
116 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
117 >();
118
119 PANIC_RESOURCES
121 .bind_to_thread_unsafe::<<ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider>();
122
123 let peripherals = static_init!(VeeRDefaultPeripherals, VeeRDefaultPeripherals::new());
124 peripherals.init();
125
126 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
128 let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);
129
130 let processes = components::process_array::ProcessArrayComponent::new()
132 .finalize(components::process_array_component_static!(NUM_PROCS));
133 PANIC_RESOURCES.get().map(|resources| {
134 resources.processes.put(processes.as_slice());
135 });
136
137 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
139
140 let uart_mux = components::console::UartMuxComponent::new(&peripherals.sim_uart, 115200)
142 .finalize(components::uart_mux_component_static!());
143
144 let mtimer = static_init!(Clint, Clint::new(&CLINT_BASE));
145
146 let mux_alarm = static_init!(MuxAlarm<'static, Clint>, MuxAlarm::new(mtimer));
149 hil::time::Alarm::set_alarm_client(mtimer, mux_alarm);
150
151 let virtual_alarm_user = static_init!(
153 VirtualMuxAlarm<'static, Clint>,
154 VirtualMuxAlarm::new(mux_alarm)
155 );
156 virtual_alarm_user.setup();
157
158 let alarm = static_init!(
159 capsules_core::alarm::AlarmDriver<'static, VirtualMuxAlarm<'static, Clint>>,
160 capsules_core::alarm::AlarmDriver::new(
161 virtual_alarm_user,
162 board_kernel.create_grant(capsules_core::alarm::DRIVER_NUM, &memory_allocation_cap)
163 )
164 );
165 hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm);
166
167 let chip = static_init!(VeeRChip, veer_el2::chip::VeeR::new(peripherals, mtimer));
168 PANIC_RESOURCES.get().map(|resources| {
169 resources.chip.put(chip);
170 });
171
172 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
174 .finalize(components::process_printer_text_component_static!());
175 PANIC_RESOURCES.get().map(|resources| {
176 resources.printer.put(process_printer);
177 });
178
179 let process_console = components::process_console::ProcessConsoleComponent::new(
180 board_kernel,
181 uart_mux,
182 mux_alarm,
183 process_printer,
184 None,
185 )
186 .finalize(components::process_console_component_static!(Clint));
187 let _ = process_console.start();
188
189 chip.enable_pic_interrupts();
191
192 csr::CSR
194 .mie
195 .modify(csr::mie::mie::mext::SET + csr::mie::mie::msoft::SET + csr::mie::mie::mtimer::SET);
196 csr::CSR.mstatus.modify(csr::mstatus::mstatus::mie::SET);
197
198 let console = components::console::ConsoleComponent::new(
200 board_kernel,
201 capsules_core::console::DRIVER_NUM,
202 uart_mux,
203 )
204 .finalize(components::console_component_static!());
205 components::debug_writer::DebugWriterComponent::new_unsafe(
207 uart_mux,
208 create_capability!(capabilities::SetDebugWriterCapability),
209 || unsafe {
210 kernel::debug::initialize_debug_writer_wrapper_unsafe::<
211 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
212 >();
213 },
214 )
215 .finalize(components::debug_writer_component_static!());
216
217 debug!("VeeR EL2 initialisation complete.");
218 debug!("Entering main loop.");
219
220 extern "C" {
222 static _sapps: u8;
224 static _eapps: u8;
226 static mut _sappmem: u8;
228 static _eappmem: u8;
230 }
231
232 let scheduler = components::sched::cooperative::CooperativeComponent::new(processes)
233 .finalize(components::cooperative_component_static!(NUM_PROCS));
234
235 let scheduler_timer =
236 components::virtual_scheduler_timer::VirtualSchedulerTimerComponent::new(mux_alarm)
237 .finalize(components::virtual_scheduler_timer_component_static!(
238 AlarmHw
239 ));
240
241 let veer = VeeR {
242 console,
243 alarm,
244 scheduler,
245 scheduler_timer,
246 };
247
248 kernel::process::load_processes(
249 board_kernel,
250 chip,
251 core::slice::from_raw_parts(
252 core::ptr::addr_of!(_sapps),
253 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
254 ),
255 core::slice::from_raw_parts_mut(
256 core::ptr::addr_of_mut!(_sappmem),
257 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
258 ),
259 &FAULT_RESPONSE,
260 &process_mgmt_cap,
261 )
262 .unwrap_or_else(|err| {
263 debug!("Error loading processes!");
264 debug!("{:?}", err);
265 });
266
267 (board_kernel, veer, chip)
268}
269
270#[no_mangle]
275pub unsafe fn main() {
276 let main_loop_cap = create_capability!(capabilities::MainLoopCapability);
277 let (board_kernel, veer, chip) = start();
278 board_kernel.kernel_loop(&veer, chip, None::<&kernel::ipc::IPC<0>>, &main_loop_cap);
279}