mirror of
https://github.com/ipxe/ipxe
synced 2026-02-01 15:29:45 +03:00
[uaccess] Generalise librm's virt_offset mechanism for RISC-V
The virtual offset memory model used for i386-pcbios and x86_64-pcbios can be generalised to also cover riscv32-sbi and riscv64-sbi. In both architectures, the 32-bit builds will use a circular map of the 32-bit address space, and the 64-bit builds will use an identity map for the relevant portion of the physical address space, with iPXE itself placed in the negative (kernel) address space. Generalise and document the virt_offset mechanism, and set it as the default for both PCBIOS and SBI platforms. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -41,6 +41,13 @@ prefix_virt:
|
||||
.dword _prefix
|
||||
.size prefix_virt, . - prefix_virt
|
||||
|
||||
/* Current virtual address offset */
|
||||
.section ".data.virt_offset", "aw", @progbits
|
||||
.globl virt_offset
|
||||
virt_offset:
|
||||
.space ( __riscv_xlen / 8 )
|
||||
.size virt_offset, . - virt_offset
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Print message to debug console
|
||||
|
||||
@@ -26,11 +26,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <elf.h>
|
||||
#include <librm.h>
|
||||
#include <ipxe/image.h>
|
||||
#include <ipxe/elf.h>
|
||||
#include <ipxe/features.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _BITS_UACCESS_H
|
||||
#define _BITS_UACCESS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* x86-specific user access API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <librm.h>
|
||||
|
||||
#endif /* _BITS_UACCESS_H */
|
||||
@@ -64,12 +64,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#else /* ASSEMBLY */
|
||||
|
||||
#ifdef UACCESS_LIBRM
|
||||
#define UACCESS_PREFIX_librm
|
||||
#else
|
||||
#define UACCESS_PREFIX_librm __librm_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Call C function from real-mode code
|
||||
*
|
||||
@@ -79,53 +73,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
"pushl $( " _S2 ( VIRTUAL ( function ) ) " )\n\t" \
|
||||
"call virt_call\n\t"
|
||||
|
||||
/* Variables in librm.S */
|
||||
extern const unsigned long virt_offset;
|
||||
|
||||
/**
|
||||
* Convert physical address to user pointer
|
||||
*
|
||||
* @v phys Physical address
|
||||
* @ret virt Virtual address
|
||||
*/
|
||||
static inline __always_inline void *
|
||||
UACCESS_INLINE ( librm, phys_to_virt ) ( unsigned long phys ) {
|
||||
|
||||
/* In a 64-bit build, any valid physical address is directly
|
||||
* usable as a virtual address, since the low 4GB is
|
||||
* identity-mapped.
|
||||
*/
|
||||
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
|
||||
return ( ( void * ) phys );
|
||||
|
||||
/* In a 32-bit build, subtract virt_offset */
|
||||
return ( ( void * ) ( 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 ( librm, virt_to_phys ) ( volatile const void *virt ) {
|
||||
physaddr_t addr = ( ( physaddr_t ) virt );
|
||||
|
||||
/* In a 64-bit build, any virtual address in the low 4GB is
|
||||
* directly usable as a physical address, since the low 4GB is
|
||||
* identity-mapped.
|
||||
*/
|
||||
if ( ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) &&
|
||||
( addr <= 0xffffffffUL ) )
|
||||
return addr;
|
||||
|
||||
/* In a 32-bit build or in a 64-bit build with a virtual
|
||||
* address above 4GB: add virt_offset
|
||||
*/
|
||||
return ( addr + virt_offset );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Access to variables in .data16 and .text16
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <registers.h>
|
||||
#include <librm.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*/
|
||||
|
||||
#include <registers.h>
|
||||
#include <librm.h>
|
||||
#include <ipxe/uaccess.h>
|
||||
#include <ipxe/timer.h>
|
||||
#include <ipxe/msr.h>
|
||||
|
||||
@@ -429,8 +429,6 @@ void setup_sipi ( unsigned int vector, uint32_t handler,
|
||||
copy_to_real ( ( vector << 8 ), 0, sipi, ( ( size_t ) sipi_len ) );
|
||||
}
|
||||
|
||||
PROVIDE_UACCESS_INLINE ( librm, phys_to_virt );
|
||||
PROVIDE_UACCESS_INLINE ( librm, virt_to_phys );
|
||||
PROVIDE_IOMAP_INLINE ( pages, io_to_bus );
|
||||
PROVIDE_IOMAP ( pages, ioremap, ioremap_pages );
|
||||
PROVIDE_IOMAP ( pages, iounmap, iounmap_pages );
|
||||
|
||||
Reference in New Issue
Block a user