From 95ede670bcfea5ea22965962fe764841243eb864 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 11 May 2025 13:04:51 +0100 Subject: [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 --- src/include/bits/virt_offset.h | 15 +++++++++++++++ src/include/ipxe/virt_offset.h | 43 +++++++----------------------------------- 2 files changed, 22 insertions(+), 36 deletions(-) create mode 100644 src/include/bits/virt_offset.h (limited to 'src/include') diff --git a/src/include/bits/virt_offset.h b/src/include/bits/virt_offset.h new file mode 100644 index 000000000..5f026284c --- /dev/null +++ b/src/include/bits/virt_offset.h @@ -0,0 +1,15 @@ +#ifndef _BITS_VIRT_OFFSET_H +#define _BITS_VIRT_OFFSET_H + +/** @file + * + * Dummy architecture-specific virtual address offset + * + * This file is included only if the architecture does not provide its + * own version of this file. + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#endif /* _BITS_VIRT_OFFSET_H */ diff --git a/src/include/ipxe/virt_offset.h b/src/include/ipxe/virt_offset.h index f8f902753..311bf12fe 100644 --- a/src/include/ipxe/virt_offset.h +++ b/src/include/ipxe/virt_offset.h @@ -54,24 +54,20 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * This is defined to be the value to be added to an address within * iPXE's own image in order to obtain its physical address, as * described above. - * - * Note that if iPXE's image is not yet writable (i.e. during early - * startup, prior to physical relocation), then this value may not yet - * be valid. Under these circumstances, callers must use - * offset_phys_to_virt() and offset_virt_to_phys() instead (and so - * provide the virtual address offset as a function parameter). */ extern const unsigned long virt_offset; +/** Allow for architecture-specific overrides of virt_offset */ +#include + /** * Convert physical address to virtual address * * @v phys Physical address - * @v offset Virtual address offset * @ret virt Virtual address */ static inline __always_inline void * -offset_phys_to_virt ( unsigned long phys, unsigned long offset ) { +UACCESS_INLINE ( offset, phys_to_virt ) ( unsigned long phys ) { /* In a 64-bit build, any valid physical address is directly * usable as a virtual address, since physical addresses are @@ -81,18 +77,17 @@ offset_phys_to_virt ( unsigned long phys, unsigned long offset ) { return ( ( void * ) phys ); /* In a 32-bit build: subtract virt_offset */ - return ( ( void * ) ( phys - offset ) ); + return ( ( void * ) ( phys - virt_offset ) ); } /** * Convert virtual address to physical address * * @v virt Virtual address - * @v offset Virtual address offset * @ret phys Physical address */ static inline __always_inline physaddr_t -offset_virt_to_phys ( volatile const void *virt, unsigned long offset ) { +UACCESS_INLINE ( offset, virt_to_phys ) ( volatile const void *virt ) { physaddr_t addr = ( ( physaddr_t ) virt ); /* In a 64-bit build, any valid virtual address with the MSB @@ -110,31 +105,7 @@ offset_virt_to_phys ( volatile const void *virt, unsigned long offset ) { /* In a 32-bit build or in a 64-bit build with a virtual * address with the MSB set: add virt_offset */ - return ( addr + offset ); -} - -/** - * Convert physical address to virtual address - * - * @v phys Physical address - * @ret virt Virtual address - */ -static inline __always_inline void * -UACCESS_INLINE ( offset, phys_to_virt ) ( unsigned long phys ) { - - return offset_phys_to_virt ( phys, virt_offset ); -} - -/** - * Convert virtual address to physical address - * - * @v virt Virtual address - * @ret phys Physical address - */ -static inline __always_inline physaddr_t -UACCESS_INLINE ( offset, virt_to_phys ) ( volatile const void *virt ) { - - return offset_virt_to_phys ( virt, virt_offset ); + return ( addr + virt_offset ); } #endif /* _IPXE_VIRT_OFFSET_H */ -- cgit v1.2.3-55-g7522