multi_core.rs 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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::{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. if hartid == 0 {
  13. true
  14. } else {
  15. let addr = 0x02000000 + hartid * 4;
  16. unsafe {
  17. // Clear IPI
  18. (addr as *mut u32).write_volatile(0);
  19. // Start listening for software interrupts
  20. mie::set_msoft();
  21. loop {
  22. wfi();
  23. if mip::read().msoft() {
  24. break;
  25. }
  26. }
  27. // Stop listening for software interrupts
  28. mie::clear_msoft();
  29. // Clear IPI
  30. (addr as *mut u32).write_volatile(0);
  31. }
  32. false
  33. }
  34. }
  35. #[entry]
  36. fn main(hartid: usize) -> ! {
  37. if hartid == 0 {
  38. // Waking hart 1...
  39. let addr = 0x02000004;
  40. unsafe {
  41. (addr as *mut u32).write_volatile(1);
  42. }
  43. }
  44. loop {}
  45. }