1#![no_std]
8#![no_main]
9
10use arty_e21_chip::chip::ArtyExxDefaultPeripherals;
11use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
12
13use kernel::capabilities;
14use kernel::component::Component;
15use kernel::hil;
16use kernel::platform::{KernelResources, SyscallDriverLookup};
17use kernel::process::ProcessArray;
18use kernel::scheduler::priority::PrioritySched;
19use kernel::{create_capability, debug, static_init};
20
21#[allow(dead_code)]
22mod timer_test;
23
24pub mod io;
25
26const NUM_PROCS: usize = 4;
30
31const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
33 capsules_system::process_policies::PanicFaultPolicy {};
34
35static mut PROCESSES: Option<&'static ProcessArray<NUM_PROCS>> = None;
37
38static mut CHIP: Option<&'static arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>> = None;
40static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
41 None;
42
43kernel::stack_size! {0x1000}
44
45struct ArtyE21 {
48 console: &'static capsules_core::console::Console<'static>,
49 gpio: &'static capsules_core::gpio::GPIO<'static, arty_e21_chip::gpio::GpioPin<'static>>,
50 alarm: &'static capsules_core::alarm::AlarmDriver<
51 'static,
52 VirtualMuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint<'static>>,
53 >,
54 led: &'static capsules_core::led::LedDriver<
55 'static,
56 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin<'static>>,
57 3,
58 >,
59 button: &'static capsules_core::button::Button<'static, arty_e21_chip::gpio::GpioPin<'static>>,
60 scheduler: &'static PrioritySched,
62}
63
64impl SyscallDriverLookup for ArtyE21 {
66 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
67 where
68 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
69 {
70 match driver_num {
71 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
72 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
73
74 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
75 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
76 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
77
78 _ => f(None),
80 }
81 }
82}
83
84impl KernelResources<arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>>
85 for ArtyE21
86{
87 type SyscallDriverLookup = Self;
88 type SyscallFilter = ();
89 type ProcessFault = ();
90 type Scheduler = PrioritySched;
91 type SchedulerTimer = ();
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 &()
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 ArtyE21,
125 &'static arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>,
126) {
127 let peripherals = static_init!(ArtyExxDefaultPeripherals, ArtyExxDefaultPeripherals::new());
128 peripherals.init();
129
130 let chip = static_init!(
131 arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>,
132 arty_e21_chip::chip::ArtyExx::new(&peripherals.machinetimer, peripherals)
133 );
134 CHIP = Some(chip);
135 chip.initialize();
136
137 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
138
139 let processes = components::process_array::ProcessArrayComponent::new()
141 .finalize(components::process_array_component_static!(NUM_PROCS));
142 PROCESSES = Some(processes);
143
144 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
145
146 kernel::debug::assign_gpios(
148 Some(&peripherals.gpio_port[0]), Some(&peripherals.gpio_port[1]), Some(&peripherals.gpio_port[8]),
151 );
152
153 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
154 .finalize(components::process_printer_text_component_static!());
155 PROCESS_PRINTER = Some(process_printer);
156
157 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
159 .finalize(components::uart_mux_component_static!());
160
161 let console = components::console::ConsoleComponent::new(
162 board_kernel,
163 capsules_core::console::DRIVER_NUM,
164 uart_mux,
165 )
166 .finalize(components::console_component_static!());
167
168 let mux_alarm = static_init!(
171 MuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint>,
172 MuxAlarm::new(&peripherals.machinetimer)
173 );
174 hil::time::Alarm::set_alarm_client(&peripherals.machinetimer, mux_alarm);
175
176 let alarm = components::alarm::AlarmDriverComponent::new(
178 board_kernel,
179 capsules_core::alarm::DRIVER_NUM,
180 mux_alarm,
181 )
182 .finalize(components::alarm_component_static!(
183 arty_e21_chip::chip::ArtyExxClint
184 ));
185
186 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
200 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin>,
201 hil::led::LedHigh::new(&peripherals.gpio_port[2]), hil::led::LedHigh::new(&peripherals.gpio_port[1]), hil::led::LedHigh::new(&peripherals.gpio_port[0]), ));
205
206 let button = components::button::ButtonComponent::new(
208 board_kernel,
209 capsules_core::button::DRIVER_NUM,
210 components::button_component_helper!(
211 arty_e21_chip::gpio::GpioPin,
212 (
213 &peripherals.gpio_port[4],
214 kernel::hil::gpio::ActivationMode::ActiveHigh,
215 kernel::hil::gpio::FloatingState::PullNone
216 )
217 ),
218 )
219 .finalize(components::button_component_static!(
220 arty_e21_chip::gpio::GpioPin
221 ));
222
223 let gpio = components::gpio::GpioComponent::new(
225 board_kernel,
226 capsules_core::gpio::DRIVER_NUM,
227 components::gpio_component_helper!(
228 arty_e21_chip::gpio::GpioPin,
229 0 => &peripherals.gpio_port[7],
230 1 => &peripherals.gpio_port[5],
231 2 => &peripherals.gpio_port[6]
232 ),
233 )
234 .finalize(components::gpio_component_static!(
235 arty_e21_chip::gpio::GpioPin
236 ));
237
238 chip.enable_all_interrupts();
239
240 let scheduler = components::sched::priority::PriorityComponent::new(board_kernel)
241 .finalize(components::priority_component_static!());
242
243 let artye21 = ArtyE21 {
244 console,
245 gpio,
246 alarm,
247 led,
248 button,
249 scheduler,
251 };
252
253 components::debug_writer::DebugWriterComponent::new(
255 uart_mux,
256 create_capability!(capabilities::SetDebugWriterCapability),
257 )
258 .finalize(components::debug_writer_component_static!());
259
260 debug!("Initialization complete. Entering main loop.");
263
264 extern "C" {
272 static _sapps: u8;
274 static _eapps: u8;
276 static mut _sappmem: u8;
278 static _eappmem: u8;
280 }
281
282 kernel::process::load_processes(
283 board_kernel,
284 chip,
285 core::slice::from_raw_parts(
286 core::ptr::addr_of!(_sapps),
287 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
288 ),
289 core::slice::from_raw_parts_mut(
290 core::ptr::addr_of_mut!(_sappmem),
291 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
292 ),
293 &FAULT_RESPONSE,
294 &process_mgmt_cap,
295 )
296 .unwrap_or_else(|err| {
297 debug!("Error loading processes!");
298 debug!("{:?}", err);
299 });
300
301 (board_kernel, artye21, chip)
302}
303
304#[no_mangle]
306pub unsafe fn main() {
307 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
308
309 let (board_kernel, board, chip) = start();
310 board_kernel.kernel_loop(
311 &board,
312 chip,
313 None::<&kernel::ipc::IPC<0>>,
314 &main_loop_capability,
315 );
316}