multi_core.rs 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #![no_std]
  2. #![no_main]
  3. extern crate panic_halt;
  4. extern crate riscv;
  5. extern crate riscv_rt;
  6. use riscv::asm::wfi;
  7. use riscv::register::{mhartid, mie, mip};
  8. use riscv_rt::entry;
  9. #[export_name = "_mp_hook"]
  10. #[rustfmt::skip]
  11. pub extern "Rust" fn user_mp_hook(hartid: usize) -> bool {
  12. let hartid = mhartid::read();
  13. if hartid == 0 {
  14. true
  15. } else {
  16. let addr = 0x02000000 + hartid * 4;
  17. unsafe {
  18. // Clear IPI
  19. (addr as *mut u32).write_volatile(0);
  20. // Start listening for software interrupts
  21. mie::set_msoft();
  22. loop {
  23. wfi();
  24. if mip::read().msoft() {
  25. break;
  26. }
  27. }
  28. // Stop listening for software interrupts
  29. mie::clear_msoft();
  30. // Clear IPI
  31. (addr as *mut u32).write_volatile(0);
  32. }
  33. false
  34. }
  35. }
  36. #[entry]
  37. fn main(hartid: usize) -> ! {
  38. if hartid == 0 {
  39. // Waking hart 1...
  40. let addr = 0x02000004;
  41. unsafe {
  42. (addr as *mut u32).write_volatile(1);
  43. }
  44. }
  45. loop {}
  46. }