1#![no_std]
8#![cfg_attr(not(doc), no_main)]
11
12use core::ptr::{addr_of, addr_of_mut};
13
14use arty_e21_chip::chip::ArtyExxDefaultPeripherals;
15use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
16
17use kernel::capabilities;
18use kernel::component::Component;
19use kernel::hil;
20use kernel::platform::{KernelResources, SyscallDriverLookup};
21use kernel::scheduler::priority::PrioritySched;
22use kernel::{create_capability, debug, static_init};
23
24#[allow(dead_code)]
25mod timer_test;
26
27pub mod io;
28
29const NUM_PROCS: usize = 4;
33
34const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
36 capsules_system::process_policies::PanicFaultPolicy {};
37
38static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
40 [None, None, None, None];
41
42static mut CHIP: Option<&'static arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>> = None;
44static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
45 None;
46
47#[no_mangle]
49#[link_section = ".stack_buffer"]
50pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
51
52struct ArtyE21 {
55 console: &'static capsules_core::console::Console<'static>,
56 gpio: &'static capsules_core::gpio::GPIO<'static, arty_e21_chip::gpio::GpioPin<'static>>,
57 alarm: &'static capsules_core::alarm::AlarmDriver<
58 'static,
59 VirtualMuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint<'static>>,
60 >,
61 led: &'static capsules_core::led::LedDriver<
62 'static,
63 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin<'static>>,
64 3,
65 >,
66 button: &'static capsules_core::button::Button<'static, arty_e21_chip::gpio::GpioPin<'static>>,
67 scheduler: &'static PrioritySched,
69}
70
71impl SyscallDriverLookup for ArtyE21 {
73 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
74 where
75 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
76 {
77 match driver_num {
78 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
79 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
80
81 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
82 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
83 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
84
85 _ => f(None),
87 }
88 }
89}
90
91impl KernelResources<arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>>
92 for ArtyE21
93{
94 type SyscallDriverLookup = Self;
95 type SyscallFilter = ();
96 type ProcessFault = ();
97 type Scheduler = PrioritySched;
98 type SchedulerTimer = ();
99 type WatchDog = ();
100 type ContextSwitchCallback = ();
101
102 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
103 self
104 }
105 fn syscall_filter(&self) -> &Self::SyscallFilter {
106 &()
107 }
108 fn process_fault(&self) -> &Self::ProcessFault {
109 &()
110 }
111 fn scheduler(&self) -> &Self::Scheduler {
112 self.scheduler
113 }
114 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
115 &()
116 }
117 fn watchdog(&self) -> &Self::WatchDog {
118 &()
119 }
120 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
121 &()
122 }
123}
124
125#[inline(never)]
129unsafe fn start() -> (
130 &'static kernel::Kernel,
131 ArtyE21,
132 &'static arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>,
133) {
134 let peripherals = static_init!(ArtyExxDefaultPeripherals, ArtyExxDefaultPeripherals::new());
135 peripherals.init();
136
137 let chip = static_init!(
138 arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>,
139 arty_e21_chip::chip::ArtyExx::new(&peripherals.machinetimer, peripherals)
140 );
141 CHIP = Some(chip);
142 chip.initialize();
143
144 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
145
146 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
147
148 kernel::debug::assign_gpios(
150 Some(&peripherals.gpio_port[0]), Some(&peripherals.gpio_port[1]), Some(&peripherals.gpio_port[8]),
153 );
154
155 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
156 .finalize(components::process_printer_text_component_static!());
157 PROCESS_PRINTER = Some(process_printer);
158
159 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
161 .finalize(components::uart_mux_component_static!());
162
163 let console = components::console::ConsoleComponent::new(
164 board_kernel,
165 capsules_core::console::DRIVER_NUM,
166 uart_mux,
167 )
168 .finalize(components::console_component_static!());
169
170 let mux_alarm = static_init!(
173 MuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint>,
174 MuxAlarm::new(&peripherals.machinetimer)
175 );
176 hil::time::Alarm::set_alarm_client(&peripherals.machinetimer, mux_alarm);
177
178 let alarm = components::alarm::AlarmDriverComponent::new(
180 board_kernel,
181 capsules_core::alarm::DRIVER_NUM,
182 mux_alarm,
183 )
184 .finalize(components::alarm_component_static!(
185 arty_e21_chip::chip::ArtyExxClint
186 ));
187
188 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
202 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin>,
203 hil::led::LedHigh::new(&peripherals.gpio_port[2]), hil::led::LedHigh::new(&peripherals.gpio_port[1]), hil::led::LedHigh::new(&peripherals.gpio_port[0]), ));
207
208 let button = components::button::ButtonComponent::new(
210 board_kernel,
211 capsules_core::button::DRIVER_NUM,
212 components::button_component_helper!(
213 arty_e21_chip::gpio::GpioPin,
214 (
215 &peripherals.gpio_port[4],
216 kernel::hil::gpio::ActivationMode::ActiveHigh,
217 kernel::hil::gpio::FloatingState::PullNone
218 )
219 ),
220 )
221 .finalize(components::button_component_static!(
222 arty_e21_chip::gpio::GpioPin
223 ));
224
225 let gpio = components::gpio::GpioComponent::new(
227 board_kernel,
228 capsules_core::gpio::DRIVER_NUM,
229 components::gpio_component_helper!(
230 arty_e21_chip::gpio::GpioPin,
231 0 => &peripherals.gpio_port[7],
232 1 => &peripherals.gpio_port[5],
233 2 => &peripherals.gpio_port[6]
234 ),
235 )
236 .finalize(components::gpio_component_static!(
237 arty_e21_chip::gpio::GpioPin
238 ));
239
240 chip.enable_all_interrupts();
241
242 let scheduler = components::sched::priority::PriorityComponent::new(board_kernel)
243 .finalize(components::priority_component_static!());
244
245 let artye21 = ArtyE21 {
246 console,
247 gpio,
248 alarm,
249 led,
250 button,
251 scheduler,
253 };
254
255 components::debug_writer::DebugWriterComponent::new(uart_mux)
257 .finalize(components::debug_writer_component_static!());
258
259 debug!("Initialization complete. Entering main loop.");
262
263 extern "C" {
271 static _sapps: u8;
273 static _eapps: u8;
275 static mut _sappmem: u8;
277 static _eappmem: u8;
279 }
280
281 kernel::process::load_processes(
282 board_kernel,
283 chip,
284 core::slice::from_raw_parts(
285 core::ptr::addr_of!(_sapps),
286 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
287 ),
288 core::slice::from_raw_parts_mut(
289 core::ptr::addr_of_mut!(_sappmem),
290 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
291 ),
292 &mut *addr_of_mut!(PROCESSES),
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}