1#![no_std]
8#![no_main]
9
10use arty_e21_chip::chip::ArtyExxDefaultPeripherals;
11use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
12
13use crate::debug::PanicResources;
14use kernel::capabilities;
15use kernel::component::Component;
16use kernel::hil;
17use kernel::platform::{KernelResources, SyscallDriverLookup};
18use kernel::scheduler::priority::PrioritySched;
19use kernel::utilities::single_thread_value::SingleThreadValue;
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
32type ChipHw = arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>;
33
34const FAULT_RESPONSE: capsules_system::process_policies::PanicFaultPolicy =
36 capsules_system::process_policies::PanicFaultPolicy {};
37
38type Chip = arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>;
39type ProcessPrinter = capsules_system::process_printer::ProcessPrinterText;
40
41static PANIC_RESOURCES: SingleThreadValue<PanicResources<Chip, ProcessPrinter>> =
43 SingleThreadValue::new(PanicResources::new());
44
45kernel::stack_size! {0x1000}
46
47struct ArtyE21 {
50 console: &'static capsules_core::console::Console<'static>,
51 gpio: &'static capsules_core::gpio::GPIO<'static, arty_e21_chip::gpio::GpioPin<'static>>,
52 alarm: &'static capsules_core::alarm::AlarmDriver<
53 'static,
54 VirtualMuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint<'static>>,
55 >,
56 led: &'static capsules_core::led::LedDriver<
57 'static,
58 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin<'static>>,
59 3,
60 >,
61 button: &'static capsules_core::button::Button<'static, arty_e21_chip::gpio::GpioPin<'static>>,
62 scheduler: &'static PrioritySched,
64}
65
66impl SyscallDriverLookup for ArtyE21 {
68 fn with_driver<F, R>(&self, driver_num: usize, f: F) -> R
69 where
70 F: FnOnce(Option<&dyn kernel::syscall::SyscallDriver>) -> R,
71 {
72 match driver_num {
73 capsules_core::console::DRIVER_NUM => f(Some(self.console)),
74 capsules_core::gpio::DRIVER_NUM => f(Some(self.gpio)),
75
76 capsules_core::alarm::DRIVER_NUM => f(Some(self.alarm)),
77 capsules_core::led::DRIVER_NUM => f(Some(self.led)),
78 capsules_core::button::DRIVER_NUM => f(Some(self.button)),
79
80 _ => f(None),
82 }
83 }
84}
85
86impl KernelResources<arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>>
87 for ArtyE21
88{
89 type SyscallDriverLookup = Self;
90 type SyscallFilter = ();
91 type ProcessFault = ();
92 type Scheduler = PrioritySched;
93 type SchedulerTimer = ();
94 type WatchDog = ();
95 type ContextSwitchCallback = ();
96
97 fn syscall_driver_lookup(&self) -> &Self::SyscallDriverLookup {
98 self
99 }
100 fn syscall_filter(&self) -> &Self::SyscallFilter {
101 &()
102 }
103 fn process_fault(&self) -> &Self::ProcessFault {
104 &()
105 }
106 fn scheduler(&self) -> &Self::Scheduler {
107 self.scheduler
108 }
109 fn scheduler_timer(&self) -> &Self::SchedulerTimer {
110 &()
111 }
112 fn watchdog(&self) -> &Self::WatchDog {
113 &()
114 }
115 fn context_switch_callback(&self) -> &Self::ContextSwitchCallback {
116 &()
117 }
118}
119
120#[inline(never)]
124unsafe fn start() -> (
125 &'static kernel::Kernel,
126 ArtyE21,
127 &'static arty_e21_chip::chip::ArtyExx<'static, ArtyExxDefaultPeripherals<'static>>,
128) {
129 kernel::deferred_call::initialize_deferred_call_state::<
131 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
132 >();
133
134 PANIC_RESOURCES.bind_to_thread::<<Chip as kernel::platform::chip::Chip>::ThreadIdProvider>();
135
136 let peripherals = static_init!(ArtyExxDefaultPeripherals, ArtyExxDefaultPeripherals::new());
137 peripherals.init();
138
139 let chip = static_init!(
140 arty_e21_chip::chip::ArtyExx<ArtyExxDefaultPeripherals>,
141 arty_e21_chip::chip::ArtyExx::new(&peripherals.machinetimer, peripherals)
142 );
143 PANIC_RESOURCES.get().map(|resources| {
144 resources.chip.put(chip);
145 });
146 chip.initialize();
147
148 let process_mgmt_cap = create_capability!(capabilities::ProcessManagementCapability);
149
150 let processes = components::process_array::ProcessArrayComponent::new()
152 .finalize(components::process_array_component_static!(NUM_PROCS));
153 PANIC_RESOURCES.get().map(|resources| {
154 resources.processes.put(processes.as_slice());
155 });
156
157 let board_kernel = static_init!(kernel::Kernel, kernel::Kernel::new(processes.as_slice()));
158
159 let debug_gpios = static_init!(
161 [&'static dyn kernel::hil::gpio::Pin; 3],
162 [
163 &peripherals.gpio_port[0],
165 &peripherals.gpio_port[1],
167 &peripherals.gpio_port[8],
168 ]
169 );
170 kernel::debug::initialize_debug_gpio::<
171 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
172 >();
173 kernel::debug::assign_gpios(debug_gpios);
174
175 let process_printer = components::process_printer::ProcessPrinterTextComponent::new()
176 .finalize(components::process_printer_text_component_static!());
177 PANIC_RESOURCES.get().map(|resources| {
178 resources.printer.put(process_printer);
179 });
180
181 let uart_mux = components::console::UartMuxComponent::new(&peripherals.uart0, 115200)
183 .finalize(components::uart_mux_component_static!());
184
185 let console = components::console::ConsoleComponent::new(
186 board_kernel,
187 capsules_core::console::DRIVER_NUM,
188 uart_mux,
189 )
190 .finalize(components::console_component_static!());
191
192 let mux_alarm = static_init!(
195 MuxAlarm<'static, arty_e21_chip::chip::ArtyExxClint>,
196 MuxAlarm::new(&peripherals.machinetimer)
197 );
198 hil::time::Alarm::set_alarm_client(&peripherals.machinetimer, mux_alarm);
199
200 let alarm = components::alarm::AlarmDriverComponent::new(
202 board_kernel,
203 capsules_core::alarm::DRIVER_NUM,
204 mux_alarm,
205 )
206 .finalize(components::alarm_component_static!(
207 arty_e21_chip::chip::ArtyExxClint
208 ));
209
210 let led = components::led::LedsComponent::new().finalize(components::led_component_static!(
224 hil::led::LedHigh<'static, arty_e21_chip::gpio::GpioPin>,
225 hil::led::LedHigh::new(&peripherals.gpio_port[2]), hil::led::LedHigh::new(&peripherals.gpio_port[1]), hil::led::LedHigh::new(&peripherals.gpio_port[0]), ));
229
230 let button = components::button::ButtonComponent::new(
232 board_kernel,
233 capsules_core::button::DRIVER_NUM,
234 components::button_component_helper!(
235 arty_e21_chip::gpio::GpioPin,
236 (
237 &peripherals.gpio_port[4],
238 kernel::hil::gpio::ActivationMode::ActiveHigh,
239 kernel::hil::gpio::FloatingState::PullNone
240 )
241 ),
242 )
243 .finalize(components::button_component_static!(
244 arty_e21_chip::gpio::GpioPin
245 ));
246
247 let gpio = components::gpio::GpioComponent::new(
249 board_kernel,
250 capsules_core::gpio::DRIVER_NUM,
251 components::gpio_component_helper!(
252 arty_e21_chip::gpio::GpioPin,
253 0 => &peripherals.gpio_port[7],
254 1 => &peripherals.gpio_port[5],
255 2 => &peripherals.gpio_port[6]
256 ),
257 )
258 .finalize(components::gpio_component_static!(
259 arty_e21_chip::gpio::GpioPin
260 ));
261
262 chip.enable_all_interrupts();
263
264 let scheduler = components::sched::priority::PriorityComponent::new(board_kernel)
265 .finalize(components::priority_component_static!());
266
267 let artye21 = ArtyE21 {
268 console,
269 gpio,
270 alarm,
271 led,
272 button,
273 scheduler,
275 };
276
277 components::debug_writer::DebugWriterComponent::new::<
279 <ChipHw as kernel::platform::chip::Chip>::ThreadIdProvider,
280 >(
281 uart_mux,
282 create_capability!(capabilities::SetDebugWriterCapability),
283 )
284 .finalize(components::debug_writer_component_static!());
285
286 debug!("Initialization complete. Entering main loop.");
289
290 extern "C" {
298 static _sapps: u8;
300 static _eapps: u8;
302 static mut _sappmem: u8;
304 static _eappmem: u8;
306 }
307
308 kernel::process::load_processes(
309 board_kernel,
310 chip,
311 core::slice::from_raw_parts(
312 core::ptr::addr_of!(_sapps),
313 core::ptr::addr_of!(_eapps) as usize - core::ptr::addr_of!(_sapps) as usize,
314 ),
315 core::slice::from_raw_parts_mut(
316 core::ptr::addr_of_mut!(_sappmem),
317 core::ptr::addr_of!(_eappmem) as usize - core::ptr::addr_of!(_sappmem) as usize,
318 ),
319 &FAULT_RESPONSE,
320 &process_mgmt_cap,
321 )
322 .unwrap_or_else(|err| {
323 debug!("Error loading processes!");
324 debug!("{:?}", err);
325 });
326
327 (board_kernel, artye21, chip)
328}
329
330#[no_mangle]
332pub unsafe fn main() {
333 let main_loop_capability = create_capability!(capabilities::MainLoopCapability);
334
335 let (board_kernel, board, chip) = start();
336 board_kernel.kernel_loop(
337 &board,
338 chip,
339 None::<&kernel::ipc::IPC<0>>,
340 &main_loop_capability,
341 );
342}