1
0

smp.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #ifndef SIFIVE_SMP
  2. #define SIFIVE_SMP
  3. // The maximum number of HARTs this code supports
  4. #ifndef MAX_HARTS
  5. #define MAX_HARTS 32
  6. #endif
  7. #define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4)
  8. // The hart that non-SMP tests should run on
  9. #ifndef NONSMP_HART
  10. #define NONSMP_HART 0
  11. #endif
  12. /* If your test cannot handle multiple-threads, use this:
  13. * smp_disable(reg1)
  14. */
  15. #define smp_disable(reg1, reg2) \
  16. csrr reg1, mhartid ;\
  17. li reg2, NONSMP_HART ;\
  18. beq reg1, reg2, hart0_entry ;\
  19. 42: ;\
  20. wfi ;\
  21. j 42b ;\
  22. hart0_entry:
  23. /* If your test needs to temporarily block multiple-threads, do this:
  24. * smp_pause(reg1, reg2)
  25. * ... single-threaded work ...
  26. * smp_resume(reg1, reg2)
  27. * ... multi-threaded work ...
  28. */
  29. #define smp_pause(reg1, reg2) \
  30. li reg2, 0x8 ;\
  31. csrw mie, reg2 ;\
  32. csrr reg2, mhartid ;\
  33. bnez reg2, 42f
  34. #define smp_resume(reg1, reg2) \
  35. li reg1, CLINT_CTRL_ADDR ;\
  36. 41: ;\
  37. li reg2, 1 ;\
  38. sw reg2, 0(reg1) ;\
  39. addi reg1, reg1, 4 ;\
  40. li reg2, CLINT_END_HART_IPI ;\
  41. blt reg1, reg2, 41b ;\
  42. 42: ;\
  43. wfi ;\
  44. csrr reg2, mip ;\
  45. andi reg2, reg2, 0x8 ;\
  46. beqz reg2, 42b ;\
  47. li reg1, CLINT_CTRL_ADDR ;\
  48. csrr reg2, mhartid ;\
  49. slli reg2, reg2, 2 ;\
  50. add reg2, reg2, reg1 ;\
  51. sw zero, 0(reg2) ;\
  52. 41: ;\
  53. lw reg2, 0(reg1) ;\
  54. bnez reg2, 41b ;\
  55. addi reg1, reg1, 4 ;\
  56. li reg2, CLINT_END_HART_IPI ;\
  57. blt reg1, reg2, 41b
  58. #endif