earlgrey_cw310/
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 earlgrey::chip_config::EarlGreyConfig;
9use kernel::debug;
10use kernel::debug::IoWrite;
11
12struct Writer {}
13
14static mut WRITER: Writer = Writer {};
15
16impl Write for Writer {
17    fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
18        self.write(s.as_bytes());
19        Ok(())
20    }
21}
22
23impl IoWrite for Writer {
24    fn write(&mut self, buf: &[u8]) -> usize {
25        // This creates a second instance of the UART peripheral, and should only be used
26        // during panic.
27        earlgrey::uart::Uart::new(
28            earlgrey::uart::UART0_BASE,
29            crate::ChipConfig::PERIPHERAL_FREQ,
30        )
31        .transmit_sync(buf);
32        buf.len()
33    }
34}
35
36#[cfg(not(test))]
37use kernel::hil::gpio::Configure;
38#[cfg(not(test))]
39use kernel::hil::led;
40
41/// Panic handler.
42#[cfg(not(test))]
43#[panic_handler]
44pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
45    use core::ptr::addr_of_mut;
46    let first_led_pin = &mut earlgrey::gpio::GpioPin::new(
47        earlgrey::gpio::GPIO_BASE,
48        earlgrey::pinmux::PadConfig::Output(
49            earlgrey::registers::top_earlgrey::MuxedPads::Ioa6,
50            earlgrey::registers::top_earlgrey::PinmuxOutsel::GpioGpio7,
51        ),
52        earlgrey::gpio::pins::pin7,
53    );
54    first_led_pin.make_output();
55    let first_led = &mut led::LedLow::new(first_led_pin);
56    let writer = &mut *addr_of_mut!(WRITER);
57
58    #[cfg(feature = "sim_verilator")]
59    debug::panic(
60        &mut [first_led],
61        writer,
62        pi,
63        &|| {},
64        crate::PANIC_RESOURCES.get(),
65    );
66
67    #[cfg(not(feature = "sim_verilator"))]
68    debug::panic(
69        &mut [first_led],
70        writer,
71        pi,
72        &rv32i::support::nop,
73        crate::PANIC_RESOURCES.get(),
74    );
75}
76
77#[cfg(test)]
78#[panic_handler]
79pub unsafe fn panic_fmt(pi: &PanicInfo) -> ! {
80    let writer = &mut WRITER;
81
82    #[cfg(feature = "sim_verilator")]
83    debug::panic_print(writer, pi, &|| {}, crate::PANIC_RESOURCES.get());
84    #[cfg(not(feature = "sim_verilator"))]
85    debug::panic_print(
86        writer,
87        pi,
88        &rv32i::support::nop,
89        crate::PANIC_RESOURCES.get(),
90    );
91
92    let _ = writeln!(writer, "{}", pi);
93    // Exit QEMU with a return code of 1
94    crate::tests::semihost_command_exit_failure();
95}