veer_el2_sim/
main.rs
1#![no_std]
9#![no_main]
10
11use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
12use kernel::capabilities;
13use kernel::component::Component;
14use kernel::hil;
15use kernel::platform::scheduler_timer::VirtualSchedulerTimer;
16use kernel::platform::{KernelResources, SyscallDriverLookup};
17use kernel::process::ProcessArray;
18use kernel::scheduler::cooperative::CooperativeSched;
19use kernel::utilities::registers::interfaces::ReadWriteable;
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>;
32
33static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
35static mut CHIP: Option<&'static VeeRChip> = 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"]
48static mut STACK_MEMORY: [u8; 0x900] = [0; 0x900];
49
50struct VeeR {
53 console: &'static capsules_core::console::Console<'static>,
54 alarm: &'static capsules_core::alarm::AlarmDriver<
55 'static,
56 VirtualMuxAlarm<'static, Clint<'static>>,
57 >,
58 scheduler: &'static CooperativeSched<'static>,
59 scheduler_timer: &'static VirtualSchedulerTimer<VirtualMuxAlarm<'static, Clint<'static>>>,
60}
61
62impl SyscallDriverLookup for VeeR {
64 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
65 where
66 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
67 {
68 match driver_num {
69 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
70 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
71 _ => f(None),
72 }
73 }
74}
75
76impl KernelResources<VeeRChip> for VeeR {
77 type SyscallDriverLookup = Self;
78 type SyscallFilter = ();
79 type ProcessFault = ();
80 type Scheduler = CooperativeSched<'static>;
81 type SchedulerTimer = VirtualSchedulerTimer<VirtualMuxAlarm<'static, Clint<'static>>>;
82 type WatchDog = ();
83 type ContextSwitchCallback = ();
84
85 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
86 self
87 }
88 fn syscall_filter(&self) -> &Self::SyscallFilter {
89 &()
90 }
91 fn process_fault(&self) -> &Self::ProcessFault {
92 &()
93 }
94 fn scheduler(&self) -> &Self::Scheduler {
95 self.scheduler
96 }
97 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
98 self.scheduler_timer
99 }
100 fn watchdog(&self) -> &Self::WatchDog {
101 &()
102 }
103 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
104 &()
105 }
106}
107
108#[inline(never)]
112unsafe fn start() -> (&'static kernel::Kernel, VeeR, &'static VeeRChip) {
113 rv32i::configure_trap_handler();
115
116 let peripherals = static_init!(VeeRDefaultPeripherals, VeeRDefaultPeripherals::new());
117 peripherals.init();
118
119 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
121 let memory_allocation_cap = create_capability!(capabilities::MemoryAllocationCapability);
122
123 let processes = components::process_array::ProcessArrayComponent::new()
125 .finalize(components::process_array_component_static!(NUM_PROCS));
126 PROCESSES = Some(processes);
127
128 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
130
131 kernel::debug::assign_gpios(None, None, None);
133
134 let uart_mux = components::console::UartMuxComponent::new(&peripherals.sim_uart, 115200)
136 .finalize(components::uart_mux_component_static!());
137
138 let mtimer = static_init!(Clint, Clint::new(&CLINT_BASE));
139
140 let mux_alarm = static_init!(MuxAlarm<'static, Clint>, MuxAlarm::new(mtimer));
143 hil::time::Alarm::set_alarm_client(mtimer, mux_alarm);
144
145 let virtual_alarm_user = static_init!(
147 VirtualMuxAlarm<'static, Clint>,
148 VirtualMuxAlarm::new(mux_alarm)
149 );
150 virtual_alarm_user.setup();
151
152 let systick_virtual_alarm = static_init!(
153 VirtualMuxAlarm<'static, Clint>,
154 VirtualMuxAlarm::new(mux_alarm)
155 );
156 systick_virtual_alarm.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 CHIP = Some(chip);
169
170 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
172 .finalize(components::process_printer_text_component_static!());
173 PROCESS_PRINTER = Some(process_printer);
174
175 let process_console = components::process_console::ProcessConsoleComponent::new(
176 board_kernel,
177 uart_mux,
178 mux_alarm,
179 process_printer,
180 None,
181 )
182 .finalize(components::process_console_component_static!(Clint));
183 let _ = process_console.start();
184
185 chip.enable_pic_interrupts();
187
188 csr::CSR
190 .mie
191 .modify(csr::mie::mie::mext::SET + csr::mie::mie::msoft::SET + csr::mie::mie::mtimer::SET);
192 csr::CSR.mstatus.modify(csr::mstatus::mstatus::mie::SET);
193
194 let console = components::console::ConsoleComponent::new(
196 board_kernel,
197 capsules_core::console::DRIVER_NUM,
198 uart_mux,
199 )
200 .finalize(components::console_component_static!());
201 components::debug_writer::DebugWriterComponent::new(
203 uart_mux,
204 create_capability!(capabilities::SetDebugWriterCapability),
205 )
206 .finalize(components::debug_writer_component_static!());
207
208 debug!("VeeR EL2 initialisation complete.");
209 debug!("Entering main loop.");
210
211 extern "C" {
213 static _sapps: u8;
215 static _eapps: u8;
217 static mut _sappmem: u8;
219 static _eappmem: u8;
221 }
222
223 let scheduler = components::sched::cooperative::CooperativeComponent::new(processes)
224 .finalize(components::cooperative_component_static!(NUM_PROCS));
225
226 let scheduler_timer = static_init!(
227 VirtualSchedulerTimer<VirtualMuxAlarm<'static, Clint<'static>>>,
228 VirtualSchedulerTimer::new(systick_virtual_alarm)
229 );
230
231 let veer = VeeR {
232 console,
233 alarm,
234 scheduler,
235 scheduler_timer,
236 };
237
238 kernel::process::load_processes(
239 board_kernel,
240 chip,
241 core::slice::from_raw_parts(
242 core::ptr::addr_of!(_sapps),
243 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
244 ),
245 core::slice::from_raw_parts_mut(
246 core::ptr::addr_of_mut!(_sappmem),
247 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
248 ),
249 &FAULT_RESPONSE,
250 &process_mgmt_cap,
251 )
252 .unwrap_or_else(|err| {
253 debug!("Error loading processes!");
254 debug!("{:?}", err);
255 });
256
257 (board_kernel, veer, chip)
258}
259
260#[no_mangle]
265pub unsafe fn main() {
266 let main_loop_cap = create_capability!(capabilities::MainLoopCapability);
267 let (board_kernel, veer, chip) = start();
268 board_kernel.kernel_loop(&veer, chip, None::<&kernel::ipc::IPC<0>>, &main_loop_cap);
269}