board.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use aclint::SifiveClint;
  2. use core::{
  3. ops::Range,
  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 struct Device {
  16. pub memory_range: Option<Range<usize>>,
  17. pub uart: Mutex<MachineConsole>,
  18. pub sifive_test: AtomicPtr<SifiveTestDevice>,
  19. pub sifive_clint: AtomicPtr<SifiveClint>,
  20. }
  21. pub struct Board<'a> {
  22. pub sbi: Sbi<'a, MachineConsole, SifiveClint, SifiveTestDevice>,
  23. pub device: Device,
  24. }
  25. pub(crate) static mut BOARD: Board<'static> = Board {
  26. device: Device {
  27. memory_range: None,
  28. #[cfg(feature = "nemu")]
  29. uart: Mutex::new(MachineConsole::UartAxiLite(MmioUartAxiLite::new(0))),
  30. #[cfg(not(feature = "nemu"))]
  31. uart: Mutex::new(MachineConsole::Uart16550(null())),
  32. sifive_test: AtomicPtr::new(null_mut()),
  33. sifive_clint: AtomicPtr::new(null_mut()),
  34. },
  35. sbi: Sbi {
  36. console: None,
  37. ipi: None,
  38. reset: None,
  39. hsm: None,
  40. rfence: None,
  41. },
  42. };
  43. /// Console Device: Uart16550
  44. #[doc(hidden)]
  45. #[allow(unused)]
  46. pub enum MachineConsole {
  47. Uart16550(*const Uart16550<u8>),
  48. UartAxiLite(MmioUartAxiLite),
  49. }
  50. unsafe impl Send for MachineConsole {}
  51. unsafe impl Sync for MachineConsole {}
  52. impl ConsoleDevice for MachineConsole {
  53. fn read(&self, buf: &mut [u8]) -> usize {
  54. match self {
  55. Self::Uart16550(uart16550) => unsafe { (**uart16550).read(buf) },
  56. Self::UartAxiLite(axilite) => axilite.read(buf),
  57. }
  58. }
  59. fn write(&self, buf: &[u8]) -> usize {
  60. match self {
  61. MachineConsole::Uart16550(uart16550) => unsafe { (**uart16550).write(buf) },
  62. Self::UartAxiLite(axilite) => axilite.write(buf),
  63. }
  64. }
  65. }
  66. // TODO: select driver follow fdt
  67. #[doc(hidden)]
  68. pub(crate) fn console_dev_init(base: usize) {
  69. let new_console = match *unsafe { BOARD.device.uart.lock() } {
  70. MachineConsole::Uart16550(_) => MachineConsole::Uart16550(base as _),
  71. MachineConsole::UartAxiLite(_) => MachineConsole::UartAxiLite(MmioUartAxiLite::new(base)),
  72. };
  73. *unsafe { BOARD.device.uart.lock() } = new_console;
  74. }
  75. /// Ipi Device: Sifive Clint
  76. impl IpiDevice for SifiveClint {
  77. #[inline(always)]
  78. fn read_mtime(&self) -> u64 {
  79. self.read_mtime()
  80. }
  81. #[inline(always)]
  82. fn write_mtime(&self, val: u64) {
  83. self.write_mtime(val)
  84. }
  85. #[inline(always)]
  86. fn read_mtimecmp(&self, hart_idx: usize) -> u64 {
  87. self.read_mtimecmp(hart_idx)
  88. }
  89. #[inline(always)]
  90. fn write_mtimecmp(&self, hart_idx: usize, val: u64) {
  91. self.write_mtimecmp(hart_idx, val)
  92. }
  93. #[inline(always)]
  94. fn read_msip(&self, hart_idx: usize) -> bool {
  95. self.read_msip(hart_idx)
  96. }
  97. #[inline(always)]
  98. fn set_msip(&self, hart_idx: usize) {
  99. self.set_msip(hart_idx)
  100. }
  101. #[inline(always)]
  102. fn clear_msip(&self, hart_idx: usize) {
  103. self.clear_msip(hart_idx)
  104. }
  105. }
  106. #[doc(hidden)]
  107. pub(crate) fn ipi_dev_init(base: usize) {
  108. unsafe {
  109. BOARD.device.sifive_clint.store(base as _, Release);
  110. }
  111. }
  112. /// Reset Device: SifiveTestDevice
  113. impl ResetDevice for SifiveTestDevice {
  114. #[inline]
  115. fn fail(&self, code: u16) -> ! {
  116. self.fail(code)
  117. }
  118. #[inline]
  119. fn pass(&self) -> ! {
  120. self.pass()
  121. }
  122. #[inline]
  123. fn reset(&self) -> ! {
  124. self.reset()
  125. }
  126. }
  127. #[doc(hidden)]
  128. pub fn reset_dev_init(base: usize) {
  129. unsafe {
  130. BOARD.device.sifive_test.store(base as _, Release);
  131. }
  132. }