riscv64.rs 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. use proc_macro2::TokenStream;
  2. use quote::quote;
  3. use syn::{Ident, Type};
  4. /// Get the base address for percpu variables of the current thread.
  5. pub fn get_percpu_pointer(percpu: &Ident, ty: &Type) -> TokenStream {
  6. quote! {
  7. {
  8. let base: *mut #ty;
  9. unsafe extern "C" {
  10. fn PERCPU_DATA_START();
  11. }
  12. ::core::arch::asm!(
  13. "la t0, {start}",
  14. "la {base}, {var}",
  15. "sub {base}, {base}, t0",
  16. "add {base}, {base}, tp",
  17. base = out(reg) base,
  18. start = sym PERCPU_DATA_START,
  19. out("t0") _,
  20. var = sym #percpu,
  21. options(nostack, preserves_flags)
  22. );
  23. base
  24. }
  25. }
  26. }
  27. pub fn get_percpu_offset(percpu: &Ident) -> TokenStream {
  28. quote! {
  29. unsafe {
  30. let offset: usize;
  31. unsafe extern "C" {
  32. fn PERCPU_DATA_START();
  33. }
  34. ::core::arch::asm!(
  35. "la t0, {start}",
  36. "la t1, {var}",
  37. "sub t1, t1, t0",
  38. start = sym PERCPU_DATA_START,
  39. var = sym #percpu,
  40. out("t0") _,
  41. out("t1") offset,
  42. options(nostack, preserves_flags)
  43. );
  44. offset
  45. }
  46. }
  47. }