clint.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // 这部分其实是运行时提供的,不应该做到实现库里面
  2. use rustsbi::SbiRet;
  3. pub struct Clint {
  4. base: usize,
  5. }
  6. impl Clint {
  7. pub fn new(base: *mut u8) -> Clint {
  8. Clint {
  9. base: base as usize,
  10. }
  11. }
  12. pub fn get_mtime(&self) -> u64 {
  13. unsafe {
  14. let base = self.base as *mut u8;
  15. core::ptr::read_volatile(base.add(0xbff8) as *mut u64)
  16. }
  17. }
  18. pub fn set_timer(&mut self, hart_id: usize, instant: u64) {
  19. unsafe {
  20. let base = self.base as *mut u8;
  21. core::ptr::write_volatile((base.offset(0x4000) as *mut u64).add(hart_id), instant);
  22. }
  23. }
  24. pub fn send_soft(&mut self, hart_id: usize) {
  25. unsafe {
  26. let base = self.base as *mut u8;
  27. core::ptr::write_volatile((base as *mut u32).add(hart_id), 1);
  28. }
  29. }
  30. pub fn clear_soft(&mut self, hart_id: usize) {
  31. unsafe {
  32. let base = self.base as *mut u8;
  33. core::ptr::write_volatile((base as *mut u32).add(hart_id), 0);
  34. }
  35. }
  36. }
  37. use rustsbi::{HartMask, Ipi, Timer};
  38. impl Ipi for Clint {
  39. fn max_hart_id(&self) -> usize {
  40. // 这个值将在初始化的时候加载,会从dtb_pa读取设备树,然后数里面有几个核
  41. *crate::MAX_HART_ID.lock()
  42. }
  43. fn send_ipi_many(&mut self, hart_mask: HartMask) -> SbiRet {
  44. for i in 0..=self.max_hart_id() {
  45. if hart_mask.has_bit(i) {
  46. self.send_soft(i);
  47. }
  48. }
  49. SbiRet::ok(0)
  50. }
  51. }
  52. impl Timer for Clint {
  53. fn set_timer(&mut self, time_value: u64) {
  54. let this_mhartid = riscv::register::mhartid::read();
  55. self.set_timer(this_mhartid, time_value);
  56. }
  57. }