clint.rs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // 这部分其实是运行时提供的,不应该做到实现库里面
  2. pub struct Clint {
  3. base: usize,
  4. }
  5. impl Clint {
  6. pub fn new(base: *mut u8) -> Clint {
  7. Clint {
  8. base: base as usize,
  9. }
  10. }
  11. pub fn get_mtime(&self) -> u64 {
  12. unsafe {
  13. let base = self.base as *mut u8;
  14. core::ptr::read_volatile(base.add(0xbff8) as *mut u64)
  15. }
  16. }
  17. pub fn set_timer(&mut self, hart_id: usize, instant: u64) {
  18. unsafe {
  19. let base = self.base as *mut u8;
  20. core::ptr::write_volatile((base.offset(0x4000) as *mut u64).add(hart_id), instant);
  21. }
  22. }
  23. pub fn send_soft(&mut self, hart_id: usize) {
  24. unsafe {
  25. let base = self.base as *mut u8;
  26. core::ptr::write_volatile((base as *mut u32).add(hart_id), 1);
  27. }
  28. }
  29. // pub fn clear_soft(&mut self, hart_id: usize) {
  30. // unsafe {
  31. // let base = self.base as *mut u8;
  32. // core::ptr::write_volatile((base as *mut u32).add(hart_id), 0);
  33. // }
  34. // }
  35. }
  36. use rustsbi::{HartMask, Ipi, Timer};
  37. impl Ipi for Clint {
  38. fn max_hart_id(&self) -> usize {
  39. let ans: usize;
  40. unsafe {
  41. asm!("
  42. lui {ans}, %hi(_max_hart_id)
  43. add {ans}, {ans}, %lo(_max_hart_id)
  44. ", ans = out(reg) ans)
  45. };
  46. ans
  47. }
  48. fn send_ipi_many(&mut self, hart_mask: HartMask) {
  49. for i in 0..=self.max_hart_id() {
  50. if hart_mask.has_bit(i) {
  51. self.send_soft(i);
  52. }
  53. }
  54. }
  55. }
  56. impl Timer for Clint {
  57. fn set_timer(&mut self, time_value: u64) {
  58. let this_mhartid = riscv::register::mhartid::read();
  59. self.set_timer(this_mhartid, time_value);
  60. }
  61. }