board.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use aclint::SifiveClint;
  2. use core::mem::MaybeUninit;
  3. use core::{
  4. ptr::{null, null_mut},
  5. sync::atomic::{AtomicPtr, Ordering::Release},
  6. };
  7. use sifive_test_device::SifiveTestDevice;
  8. use spin::Mutex;
  9. use uart16550::Uart16550;
  10. use uart_xilinx::uart_lite::uart::MmioUartAxiLite;
  11. use crate::sbi::console::ConsoleDevice;
  12. use crate::sbi::ipi::IpiDevice;
  13. use crate::sbi::reset::ResetDevice;
  14. use crate::sbi::SBI;
  15. pub(crate) static mut SBI_IMPL: MaybeUninit<
  16. SBI<'static, MachineConsole, SifiveClint, SifiveTestDevice>,
  17. > = MaybeUninit::uninit();
  18. /// Console Device: Uart16550
  19. #[doc(hidden)]
  20. #[allow(unused)]
  21. pub enum MachineConsole {
  22. Uart16550(*const Uart16550<u8>),
  23. UartAxiLite(MmioUartAxiLite),
  24. }
  25. unsafe impl Send for MachineConsole {}
  26. unsafe impl Sync for MachineConsole {}
  27. impl ConsoleDevice for MachineConsole {
  28. fn read(&self, buf: &mut [u8]) -> usize {
  29. match self {
  30. Self::Uart16550(uart16550) => unsafe { (**uart16550).read(buf) },
  31. Self::UartAxiLite(axilite) => axilite.read(buf),
  32. }
  33. }
  34. fn write(&self, buf: &[u8]) -> usize {
  35. match self {
  36. MachineConsole::Uart16550(uart16550) => unsafe { (**uart16550).write(buf) },
  37. Self::UartAxiLite(axilite) => axilite.write(buf),
  38. }
  39. }
  40. }
  41. // TODO: select driver follow fdt
  42. #[doc(hidden)]
  43. #[cfg(feature = "nemu")]
  44. pub(crate) static UART: Mutex<MachineConsole> =
  45. Mutex::new(MachineConsole::UartAxiLite(MmioUartAxiLite::new(0)));
  46. #[cfg(not(feature = "nemu"))]
  47. pub(crate) static UART: Mutex<MachineConsole> = Mutex::new(MachineConsole::Uart16550(null()));
  48. pub(crate) fn console_dev_init(base: usize) {
  49. let new_console = match *UART.lock() {
  50. MachineConsole::Uart16550(_) => MachineConsole::Uart16550(base as _),
  51. MachineConsole::UartAxiLite(_) => MachineConsole::UartAxiLite(MmioUartAxiLite::new(base)),
  52. };
  53. *UART.lock() = new_console;
  54. }
  55. /// Ipi Device: Sifive Clint
  56. impl IpiDevice for SifiveClint {
  57. #[inline(always)]
  58. fn read_mtime(&self) -> u64 {
  59. self.read_mtime()
  60. }
  61. #[inline(always)]
  62. fn write_mtime(&self, val: u64) {
  63. self.write_mtime(val)
  64. }
  65. #[inline(always)]
  66. fn read_mtimecmp(&self, hart_idx: usize) -> u64 {
  67. self.read_mtimecmp(hart_idx)
  68. }
  69. #[inline(always)]
  70. fn write_mtimecmp(&self, hart_idx: usize, val: u64) {
  71. self.write_mtimecmp(hart_idx, val)
  72. }
  73. #[inline(always)]
  74. fn read_msip(&self, hart_idx: usize) -> bool {
  75. self.read_msip(hart_idx)
  76. }
  77. #[inline(always)]
  78. fn set_msip(&self, hart_idx: usize) {
  79. self.set_msip(hart_idx)
  80. }
  81. #[inline(always)]
  82. fn clear_msip(&self, hart_idx: usize) {
  83. self.clear_msip(hart_idx)
  84. }
  85. }
  86. #[doc(hidden)]
  87. pub(crate) static SIFIVECLINT: AtomicPtr<SifiveClint> = AtomicPtr::new(null_mut());
  88. pub(crate) fn ipi_dev_init(base: usize) {
  89. SIFIVECLINT.store(base as _, Release);
  90. }
  91. /// Reset Device: SifiveTestDevice
  92. impl ResetDevice for SifiveTestDevice {
  93. #[inline]
  94. fn fail(&self, code: u16) -> ! {
  95. self.fail(code)
  96. }
  97. #[inline]
  98. fn pass(&self) -> ! {
  99. self.pass()
  100. }
  101. #[inline]
  102. fn reset(&self) -> ! {
  103. self.reset()
  104. }
  105. }
  106. #[doc(hidden)]
  107. pub(crate) static SIFIVETEST: AtomicPtr<SifiveTestDevice> = AtomicPtr::new(null_mut());
  108. pub fn reset_dev_init(base: usize) {
  109. SIFIVETEST.store(base as _, Release);
  110. }