#ifndef _BITS_VIRT_OFFSET_H #define _BITS_VIRT_OFFSET_H /** @file * * RISCV-specific virtual address offset * * We use the thread pointer register (tp) to hold the virtual address * offset, so that virtual-to-physical address translations work as * expected even while we are executing directly from read-only memory * (and so cannot store a value in a global virt_offset variable). * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Read virtual address offset held in thread pointer register * * @ret virt_offset Virtual address offset */ static inline __attribute__ (( const, always_inline )) unsigned long tp_virt_offset ( void ) { register unsigned long tp asm ( "tp" ); __asm__ ( "" : "=r" ( tp ) ); return tp; } /** Always read thread pointer register to get virtual address offset */ #define virt_offset tp_virt_offset() #endif /* _BITS_VIRT_OFFSET_H */