asm.rs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //! Assembly instructions
  2. macro_rules! instruction {
  3. ($(#[$attr:meta])*, $fnname:ident, $asm:expr, $asm_fn:ident) => (
  4. $(#[$attr])*
  5. #[inline]
  6. pub unsafe fn $fnname() {
  7. match () {
  8. #[cfg(all(riscv, feature = "inline-asm"))]
  9. () => asm!($asm :::: "volatile"),
  10. #[cfg(all(riscv, not(feature = "inline-asm")))]
  11. () => {
  12. extern "C" {
  13. fn $asm_fn();
  14. }
  15. $asm_fn();
  16. }
  17. #[cfg(not(riscv))]
  18. () => unimplemented!(),
  19. }
  20. }
  21. )
  22. }
  23. instruction!(
  24. /// `EBREAK` instruction wrapper
  25. ///
  26. /// Generates a breakpoint exception.
  27. , ebreak, "ebreak", __ebreak);
  28. instruction!(
  29. /// `WFI` instruction wrapper
  30. ///
  31. /// Provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing.
  32. /// The WFI instruction is just a hint, and a legal implementation is to implement WFI as a NOP.
  33. , wfi, "wfi", __wfi);
  34. instruction!(
  35. /// `SFENCE.VMA` instruction wrapper (all address spaces and page table levels)
  36. ///
  37. /// Synchronizes updates to in-memory memory-management data structures with current execution.
  38. /// Instruction execution causes implicit reads and writes to these data structures; however, these implicit references
  39. /// are ordinarily not ordered with respect to loads and stores in the instruction stream.
  40. /// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the
  41. /// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`.
  42. , sfence_vma_all, "sfence.vma", __sfence_vma_all);
  43. /// `SFENCE.VMA` instruction wrapper
  44. ///
  45. /// Synchronizes updates to in-memory memory-management data structures with current execution.
  46. /// Instruction execution causes implicit reads and writes to these data structures; however, these implicit references
  47. /// are ordinarily not ordered with respect to loads and stores in the instruction stream.
  48. /// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the
  49. /// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`.
  50. #[inline]
  51. #[allow(unused_variables)]
  52. pub unsafe fn sfence_vma(asid: usize, addr: usize) {
  53. match () {
  54. #[cfg(all(riscv, feature = "inline-asm"))]
  55. () => asm!("sfence.vma $0, $1" :: "r"(asid), "r"(addr) :: "volatile"),
  56. #[cfg(all(riscv, not(feature = "inline-asm")))]
  57. () => {
  58. extern "C" {
  59. fn __sfence_vma(asid: usize, addr: usize);
  60. }
  61. __sfence_vma(asid, addr);
  62. }
  63. #[cfg(not(riscv))]
  64. () => unimplemented!(),
  65. }
  66. }