litex_arty/
io.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use core::fmt::Write;
6use core::panic::PanicInfo;
7use core::str;
8use kernel::debug;
9use kernel::debug::IoWrite;
10
11struct Writer {
12    uart: litex_vexriscv::uart::LiteXUart<'static, crate::socc::SoCRegisterFmt>,
13}
14
15impl Write for Writer {
16    fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
17        self.write(s.as_bytes());
18        Ok(())
19    }
20}
21
22impl IoWrite for Writer {
23    fn write(&mut self, buf: &[u8]) -> usize {
24        self.uart.transmit_sync(buf);
25        buf.len()
26    }
27}
28
29/// Panic handler.
30#[cfg(not(test))]
31#[panic_handler]
32pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
33    // TODO: this double-instantiates the LiteX UART. `transmit_sync` should be
34    // converted into an unsafe, static method instead (which can take over UART
35    // operation with the hardware in any arbitrary state, and where the caller
36    // guarantees that the regular UART driver will not run following any call
37    // to `transmit_sync`)
38    let mut writer = Writer {
39        uart: litex_vexriscv::uart::LiteXUart::new(
40            kernel::utilities::StaticRef::new(
41                crate::socc::CSR_UART_BASE
42                    as *const litex_vexriscv::uart::LiteXUartRegisters<crate::socc::SoCRegisterFmt>,
43            ),
44            None, // LiteX simulator has no UART phy
45        ),
46    };
47
48    // TODO: this double-initializes the LED controller. Similar to the UART
49    // above, this should have the `panic_led` function be static and unsafe,
50    // with a guarantee that the rest of the controller will not run after this
51    // function is called once:
52    let led0 = litex_vexriscv::led_controller::LiteXLedController::new(
53        kernel::utilities::StaticRef::new(
54            crate::socc::CSR_LEDS_BASE
55                as *const litex_vexriscv::led_controller::LiteXLedRegisters<
56                    crate::socc::SoCRegisterFmt,
57                >,
58        ),
59        4, // 4 LEDs on this board
60    );
61    let panic_led = led0.panic_led(0);
62
63    debug::panic(
64        &mut [&mut panic_led.unwrap()],
65        &mut writer,
66        pi,
67        &rv32i::support::nop,
68        crate::PANIC_RESOURCES.get(),
69    )
70}