1#![no_std]
8#![no_main]
9
10use core::ptr::{addr_of, addr_of_mut};
11
12use arty_e21_chip::chip::ArtyExxDefaultPeripherals;
13use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
14
15use kernel::capabilities;
16use kernel::component::Component;
17use kernel::hil;
18use kernel::platform::{KernelResources, SyscallDriverLookup};
19use kernel::scheduler::priority::PrioritySched;
20use kernel::{create_capability, debug, static_init};
21
22#[allow(dead_code)]
23mod timer_test;
24
25pub mod io;
26
27const NUM_PROCS: usize = 4;
31
32const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
34 capsules_system::process_policies::PanicFaultPolicy {};
35
36static mut PROCESSES: [Option<&'static dyn kernel::process::Process>; NUM_PROCS] =
38 [None, None, None, None];
39
40static mut CHIP: Option<&'static arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>> = None;
42static mut PROCESS_PRINTER: Option<&'static capsules_system::process_printer::ProcessPrinterText> =
43 None;
44
45#[no_mangle]
47#[link_section = ".stack_buffer"]
48pub static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
49
50struct ArtyE21 {
53 console: &'static capsules_core::console::Console<'static>,
54 gpio: &'static capsules_core::gpio::GPIO<'static, arty_e21_chip::gpio::GpioPin<'static>>,
55 alarm: &'static capsules_core::alarm::AlarmDriver<
56 'static,
57 VirtualMuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint<'static>>,
58 >,
59 led: &'static capsules_core::led::LedDriver<
60 'static,
61 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin<'static>>,
62 3,
63 >,
64 button: &'static capsules_core::button::Button<'static, arty_e21_chip::gpio::GpioPin<'static>>,
65 scheduler: &'static PrioritySched,
67}
68
69impl SyscallDriverLookup for ArtyE21 {
71 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
72 where
73 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
74 {
75 match driver_num {
76 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
77 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
78
79 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
80 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
81 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
82
83 _ => f(None),
85 }
86 }
87}
88
89impl KernelResources<arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>>
90 for ArtyE21
91{
92 type SyscallDriverLookup = Self;
93 type SyscallFilter = ();
94 type ProcessFault = ();
95 type Scheduler = PrioritySched;
96 type SchedulerTimer = ();
97 type WatchDog = ();
98 type ContextSwitchCallback = ();
99
100 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
101 self
102 }
103 fn syscall_filter(&self) -> &Self::SyscallFilter {
104 &()
105 }
106 fn process_fault(&self) -> &Self::ProcessFault {
107 &()
108 }
109 fn scheduler(&self) -> &Self::Scheduler {
110 self.scheduler
111 }
112 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
113 &()
114 }
115 fn watchdog(&self) -> &Self::WatchDog {
116 &()
117 }
118 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
119 &()
120 }
121}
122
123#[inline(never)]
127unsafe fn start() -> (
128 &'static kernel::Kernel,
129 ArtyE21,
130 &'static arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>,
131) {
132 let peripherals = static_init!(ArtyExxDefaultPeripherals, ArtyExxDefaultPeripherals::new());
133 peripherals.init();
134
135 let chip = static_init!(
136 arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>,
137 arty_e21_chip::chip::ArtyExx::new(&peripherals.machinetimer, peripherals)
138 );
139 CHIP = Some(chip);
140 chip.initialize();
141
142 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
143
144 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(&*addr_of!(PROCESSES)));
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 &mut *addr_of_mut!(PROCESSES),
294 &FAULT_RESPONSE,
295 &process_mgmt_cap,
296 )
297 .unwrap_or_else(|err| {
298 debug!("Error loading processes!");
299 debug!("{:?}", err);
300 });
301
302 (board_kernel, artye21, chip)
303}
304
305#[no_mangle]
307pub unsafe fn main() {
308 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
309
310 let (board_kernel, board, chip) = start();
311 board_kernel.kernel_loop(
312 &board,
313 chip,
314 None::<&kernel::ipc::IPC<0>>,
315 &main_loop_capability,
316 );
317}