| #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 ); | |
| FILE_SECBOOT ( PERMITTED ); | |
| /** | |
| * 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 */ |