blob: 83ac175514def7d5fb41210dc509d4308bf4b54d [file] [log] [blame]
#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 */