123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- use aclint::SifiveClint;
- use core::{
- ops::Range,
- ptr::{null, null_mut},
- sync::atomic::{AtomicPtr, Ordering::Release},
- };
- use sifive_test_device::SifiveTestDevice;
- use spin::Mutex;
- use uart16550::Uart16550;
- use uart_xilinx::uart_lite::uart::MmioUartAxiLite;
- use crate::sbi::console::ConsoleDevice;
- use crate::sbi::ipi::IpiDevice;
- use crate::sbi::reset::ResetDevice;
- use crate::sbi::Sbi;
- pub struct Device {
- pub memory_range: Option<Range<usize>>,
- pub uart: Mutex<MachineConsole>,
- pub sifive_test: AtomicPtr<SifiveTestDevice>,
- pub sifive_clint: AtomicPtr<SifiveClint>,
- }
- pub struct Board<'a> {
- pub sbi: Sbi<'a, MachineConsole, SifiveClint, SifiveTestDevice>,
- pub device: Device,
- }
- pub(crate) static mut BOARD: Board<'static> = Board {
- device: Device {
- memory_range: None,
- #[cfg(feature = "nemu")]
- uart: Mutex::new(MachineConsole::UartAxiLite(MmioUartAxiLite::new(0))),
- #[cfg(not(feature = "nemu"))]
- uart: Mutex::new(MachineConsole::Uart16550(null())),
- sifive_test: AtomicPtr::new(null_mut()),
- sifive_clint: AtomicPtr::new(null_mut()),
- },
- sbi: Sbi {
- console: None,
- ipi: None,
- reset: None,
- hsm: None,
- rfence: None,
- },
- };
- /// Console Device: Uart16550
- #[doc(hidden)]
- #[allow(unused)]
- pub enum MachineConsole {
- Uart16550(*const Uart16550<u8>),
- UartAxiLite(MmioUartAxiLite),
- }
- unsafe impl Send for MachineConsole {}
- unsafe impl Sync for MachineConsole {}
- impl ConsoleDevice for MachineConsole {
- fn read(&self, buf: &mut [u8]) -> usize {
- match self {
- Self::Uart16550(uart16550) => unsafe { (**uart16550).read(buf) },
- Self::UartAxiLite(axilite) => axilite.read(buf),
- }
- }
- fn write(&self, buf: &[u8]) -> usize {
- match self {
- MachineConsole::Uart16550(uart16550) => unsafe { (**uart16550).write(buf) },
- Self::UartAxiLite(axilite) => axilite.write(buf),
- }
- }
- }
- // TODO: select driver follow fdt
- #[doc(hidden)]
- pub(crate) fn console_dev_init(base: usize) {
- let new_console = match *unsafe { BOARD.device.uart.lock() } {
- MachineConsole::Uart16550(_) => MachineConsole::Uart16550(base as _),
- MachineConsole::UartAxiLite(_) => MachineConsole::UartAxiLite(MmioUartAxiLite::new(base)),
- };
- *unsafe { BOARD.device.uart.lock() } = new_console;
- }
- /// Ipi Device: Sifive Clint
- impl IpiDevice for SifiveClint {
- #[inline(always)]
- fn read_mtime(&self) -> u64 {
- self.read_mtime()
- }
- #[inline(always)]
- fn write_mtime(&self, val: u64) {
- self.write_mtime(val)
- }
- #[inline(always)]
- fn read_mtimecmp(&self, hart_idx: usize) -> u64 {
- self.read_mtimecmp(hart_idx)
- }
- #[inline(always)]
- fn write_mtimecmp(&self, hart_idx: usize, val: u64) {
- self.write_mtimecmp(hart_idx, val)
- }
- #[inline(always)]
- fn read_msip(&self, hart_idx: usize) -> bool {
- self.read_msip(hart_idx)
- }
- #[inline(always)]
- fn set_msip(&self, hart_idx: usize) {
- self.set_msip(hart_idx)
- }
- #[inline(always)]
- fn clear_msip(&self, hart_idx: usize) {
- self.clear_msip(hart_idx)
- }
- }
- #[doc(hidden)]
- pub(crate) fn ipi_dev_init(base: usize) {
- unsafe {
- BOARD.device.sifive_clint.store(base as _, Release);
- }
- }
- /// Reset Device: SifiveTestDevice
- impl ResetDevice for SifiveTestDevice {
- #[inline]
- fn fail(&self, code: u16) -> ! {
- self.fail(code)
- }
- #[inline]
- fn pass(&self) -> ! {
- self.pass()
- }
- #[inline]
- fn reset(&self) -> ! {
- self.reset()
- }
- }
- #[doc(hidden)]
- pub fn reset_dev_init(base: usize) {
- unsafe {
- BOARD.device.sifive_test.store(base as _, Release);
- }
- }
|