// SPDX-License-Identifier: MIT OR Apache-2.0 // // Copyright (c) 2018-2020 Andre Richter //! BSP console facilities. use super::memory; use crate::{bsp::device_driver, console, cpu}; use core::fmt; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- /// In case of a panic, the panic handler uses this function to take a last shot at printing /// something before the system is halted. /// /// We try to init panic-versions of the GPIO and the UART. The panic versions are not protected /// with synchronization primitives, which increases chances that we get to print something, even /// when the kernel's default GPIO or UART instances happen to be locked at the time of the panic. /// /// # Safety /// /// - Use only for printing during a panic. pub unsafe fn panic_console_out() -> impl fmt::Write { use crate::driver::interface::DeviceDriver; let mut panic_gpio = device_driver::PanicGPIO::new(memory::map::mmio::GPIO_START.into_usize()); let mut panic_uart = device_driver::PanicUart::new(memory::map::mmio::PL011_UART_START.into_usize()); // If remapping of the driver's MMIO already happened, take the remapped start address. // Otherwise, take a chance with the default physical address. let maybe_gpio_mmio_start_addr = super::GPIO.virt_mmio_start_addr(); let maybe_uart_mmio_start_addr = super::PL011_UART.virt_mmio_start_addr(); panic_gpio .init(maybe_gpio_mmio_start_addr) .unwrap_or_else(|_| cpu::wait_forever()); panic_gpio.map_pl011_uart(); panic_uart .init(maybe_uart_mmio_start_addr) .unwrap_or_else(|_| cpu::wait_forever()); panic_uart } /// Return a reference to the console. pub fn console() -> &'static impl console::interface::All { &super::PL011_UART } //-------------------------------------------------------------------------------------------------- // Testing //-------------------------------------------------------------------------------------------------- /// Minimal code needed to bring up the console in QEMU (for testing only). This is often less steps /// than on real hardware due to QEMU's abstractions. /// /// For the RPi, nothing needs to be done. pub fn qemu_bring_up_console() {}