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
43#[no_mangle]
45#[link_section = ".stack_buffer"]
46static mut STACK_MEMORY: [u8; 0x1000] = [0; 0x1000];
47
48struct ArtyE21 {
51 console: &'static capsules_core::console::Console<'static>,
52 gpio: &'static capsules_core::gpio::GPIO<'static, arty_e21_chip::gpio::GpioPin<'static>>,
53 alarm: &'static capsules_core::alarm::AlarmDriver<
54 'static,
55 VirtualMuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint<'static>>,
56 >,
57 led: &'static capsules_core::led::LedDriver<
58 'static,
59 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin<'static>>,
60 3,
61 >,
62 button: &'static capsules_core::button::Button<'static, arty_e21_chip::gpio::GpioPin<'static>>,
63 scheduler: &'static PrioritySched,
65}
66
67impl SyscallDriverLookup for ArtyE21 {
69 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
70 where
71 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
72 {
73 match driver_num {
74 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
75 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
76
77 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
78 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
79 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
80
81 _ => f(None),
83 }
84 }
85}
86
87impl KernelResources<arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>>
88 for ArtyE21
89{
90 type SyscallDriverLookup = Self;
91 type SyscallFilter = ();
92 type ProcessFault = ();
93 type Scheduler = PrioritySched;
94 type SchedulerTimer = ();
95 type WatchDog = ();
96 type ContextSwitchCallback = ();
97
98 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
99 self
100 }
101 fn syscall_filter(&self) -> &Self::SyscallFilter {
102 &()
103 }
104 fn process_fault(&self) -> &Self::ProcessFault {
105 &()
106 }
107 fn scheduler(&self) -> &Self::Scheduler {
108 self.scheduler
109 }
110 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
111 &()
112 }
113 fn watchdog(&self) -> &Self::WatchDog {
114 &()
115 }
116 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
117 &()
118 }
119}
120
121#[inline(never)]
125unsafe fn start() -> (
126 &'static kernel::Kernel,
127 ArtyE21,
128 &'static arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>,
129) {
130 let peripherals = static_init!(ArtyExxDefaultPeripherals, ArtyExxDefaultPeripherals::new());
131 peripherals.init();
132
133 let chip = static_init!(
134 arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>,
135 arty_e21_chip::chip::ArtyExx::new(&peripherals.machinetimer, peripherals)
136 );
137 CHIP = Some(chip);
138 chip.initialize();
139
140 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
141
142 let processes = components::process_array::ProcessArrayComponent::new()
144 .finalize(components::process_array_component_static!(NUM_PROCS));
145 PROCESSES = Some(processes);
146
147 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
148
149 kernel::debug::assign_gpios(
151 Some(&peripherals.gpio_port[0]), Some(&peripherals.gpio_port[1]), Some(&peripherals.gpio_port[8]),
154 );
155
156 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
157 .finalize(components::process_printer_text_component_static!());
158 PROCESS_PRINTER = Some(process_printer);
159
160 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
162 .finalize(components::uart_mux_component_static!());
163
164 let console = components::console::ConsoleComponent::new(
165 board_kernel,
166 capsules_core::console::DRIVER_NUM,
167 uart_mux,
168 )
169 .finalize(components::console_component_static!());
170
171 let mux_alarm = static_init!(
174 MuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint>,
175 MuxAlarm::new(&peripherals.machinetimer)
176 );
177 hil::time::Alarm::set_alarm_client(&peripherals.machinetimer, mux_alarm);
178
179 let alarm = components::alarm::AlarmDriverComponent::new(
181 board_kernel,
182 capsules_core::alarm::DRIVER_NUM,
183 mux_alarm,
184 )
185 .finalize(components::alarm_component_static!(
186 arty_e21_chip::chip::ArtyExxClint
187 ));
188
189 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
203 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin>,
204 hil::led::LedHigh::new(&peripherals.gpio_port[2]), hil::led::LedHigh::new(&peripherals.gpio_port[1]), hil::led::LedHigh::new(&peripherals.gpio_port[0]), ));
208
209 let button = components::button::ButtonComponent::new(
211 board_kernel,
212 capsules_core::button::DRIVER_NUM,
213 components::button_component_helper!(
214 arty_e21_chip::gpio::GpioPin,
215 (
216 &peripherals.gpio_port[4],
217 kernel::hil::gpio::ActivationMode::ActiveHigh,
218 kernel::hil::gpio::FloatingState::PullNone
219 )
220 ),
221 )
222 .finalize(components::button_component_static!(
223 arty_e21_chip::gpio::GpioPin
224 ));
225
226 let gpio = components::gpio::GpioComponent::new(
228 board_kernel,
229 capsules_core::gpio::DRIVER_NUM,
230 components::gpio_component_helper!(
231 arty_e21_chip::gpio::GpioPin,
232 0 => &peripherals.gpio_port[7],
233 1 => &peripherals.gpio_port[5],
234 2 => &peripherals.gpio_port[6]
235 ),
236 )
237 .finalize(components::gpio_component_static!(
238 arty_e21_chip::gpio::GpioPin
239 ));
240
241 chip.enable_all_interrupts();
242
243 let scheduler = components::sched::priority::PriorityComponent::new(board_kernel)
244 .finalize(components::priority_component_static!());
245
246 let artye21 = ArtyE21 {
247 console,
248 gpio,
249 alarm,
250 led,
251 button,
252 scheduler,
254 };
255
256 components::debug_writer::DebugWriterComponent::new(
258 uart_mux,
259 create_capability!(capabilities::SetDebugWriterCapability),
260 )
261 .finalize(components::debug_writer_component_static!());
262
263 debug!("Initialization complete. Entering main loop.");
266
267 extern "C" {
275 static _sapps: u8;
277 static _eapps: u8;
279 static mut _sappmem: u8;
281 static _eappmem: u8;
283 }
284
285 kernel::process::load_processes(
286 board_kernel,
287 chip,
288 core::slice::from_raw_parts(
289 core::ptr::addr_of!(_sapps),
290 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
291 ),
292 core::slice::from_raw_parts_mut(
293 core::ptr::addr_of_mut!(_sappmem),
294 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
295 ),
296 &FAULT_RESPONSE,
297 &process_mgmt_cap,
298 )
299 .unwrap_or_else(|err| {
300 debug!("Error loading processes!");
301 debug!("{:?}", err);
302 });
303
304 (board_kernel, artye21, chip)
305}
306
307#[no_mangle]
309pub unsafe fn main() {
310 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
311
312 let (board_kernel, board, chip) = start();
313 board_kernel.kernel_loop(
314 &board,
315 chip,
316 None::<&kernel::ipc::IPC<0>>,
317 &main_loop_capability,
318 );
319}