diff options
| author | Michael Brown | 2025-05-11 14:04:51 +0200 |
|---|---|---|
| committer | Michael Brown | 2025-05-11 14:46:21 +0200 |
| commit | 95ede670bcfea5ea22965962fe764841243eb864 (patch) | |
| tree | b7a18723d1b1ad6cf034e2478632471d2a9bf258 /src/arch/riscv/include | |
| parent | [fdt] Generalise access to "reg" property (diff) | |
| download | ipxe-95ede670bcfea5ea22965962fe764841243eb864.tar.gz ipxe-95ede670bcfea5ea22965962fe764841243eb864.tar.xz ipxe-95ede670bcfea5ea22965962fe764841243eb864.zip | |
[riscv] Hold virtual address offset in the thread pointer register
iPXE does not make use of any thread-local storage. Use the otherwise
unused thread pointer register ("tp") to hold the current value of
the virtual address offset, rather than using a global variable.
This ensures that virt_offset can be made valid even during very early
initialisation (when iPXE may be executing directly from read-only
memory and so cannot update a global variable).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch/riscv/include')
| -rw-r--r-- | src/arch/riscv/include/bits/virt_offset.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/arch/riscv/include/bits/virt_offset.h b/src/arch/riscv/include/bits/virt_offset.h new file mode 100644 index 000000000..83ac17551 --- /dev/null +++ b/src/arch/riscv/include/bits/virt_offset.h @@ -0,0 +1,33 @@ +#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 */ |
