| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- use proc_macro2::TokenStream;
- use quote::quote;
- use syn::{Ident, Type};
- /// Get the base address for percpu variables of the current thread.
- pub fn get_percpu_pointer(percpu: &Ident, ty: &Type) -> TokenStream {
- quote! {
- {
- let base: *mut #ty;
- unsafe extern "C" {
- fn PERCPU_DATA_START();
- }
- ::core::arch::asm!(
- "sub.d {base}, {base}, {start}",
- "add.d {base}, {base}, $tp",
- base = inout(reg) &raw const #percpu => base,
- start = in(reg) PERCPU_DATA_START as usize,
- options(nostack, preserves_flags)
- );
- base
- }
- }
- }
- pub fn get_percpu_offset(percpu: &Ident) -> TokenStream {
- quote! {
- unsafe {
- let offset: usize;
- unsafe extern "C" {
- fn PERCPU_DATA_START();
- }
- ::core::arch::asm!(
- "la.global {tmp}, {start}",
- "la.global {output}, {var}",
- "sub.d {output}, {output}, {tmp}",
- start = sym PERCPU_DATA_START,
- var = sym #percpu,
- tmp = out(reg) _,
- output = out(reg) offset,
- options(nostack, preserves_flags)
- );
- offset
- }
- }
- }
|