litex_sim/
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    debug::panic_print(
49        &mut writer,
50        pi,
51        &rv32i::support::nop,
52        crate::PANIC_RESOURCES.get(),
53    );
54
55    // The system is no longer in a well-defined state; loop forever
56    loop {}
57}