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