mirror of
https://github.com/ipxe/ipxe
synced 2026-04-16 03:00:10 +03:00
[riscv] Add support for the RISC-V CPU architecture
Add support for building iPXE as a 64-bit or 32-bit RISC-V binary, for
either UEFI or Linux userspace platforms. For example:
# RISC-V 64-bit UEFI
make CROSS=riscv64-linux-gnu- bin-riscv64-efi/ipxe.efi
# RISC-V 32-bit UEFI
make CROSS=riscv64-linux-gnu- bin-riscv32-efi/ipxe.efi
# RISC-V 64-bit Linux
make CROSS=riscv64-linux-gnu- bin-riscv64-linux/tests.linux
qemu-riscv64 -L /usr/riscv64-linux-gnu/sys-root \
./bin-riscv64-linux/tests.linux
# RISC-V 32-bit Linux
make CROSS=riscv64-linux-gnu- SYSROOT=/usr/riscv32-linux-gnu/sys-root \
bin-riscv32-linux/tests.linux
qemu-riscv32 -L /usr/riscv32-linux-gnu/sys-root \
./bin-riscv32-linux/tests.linux
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -91,11 +91,13 @@ static void read_pe_info ( void *pe, uint16_t *machine,
|
||||
switch ( *machine ) {
|
||||
case EFI_IMAGE_MACHINE_IA32:
|
||||
case EFI_IMAGE_MACHINE_ARMTHUMB_MIXED:
|
||||
case EFI_IMAGE_MACHINE_RISCV32:
|
||||
*subsystem = nt->nt32.OptionalHeader.Subsystem;
|
||||
break;
|
||||
case EFI_IMAGE_MACHINE_X64:
|
||||
case EFI_IMAGE_MACHINE_AARCH64:
|
||||
case EFI_IMAGE_MACHINE_LOONGARCH64:
|
||||
case EFI_IMAGE_MACHINE_RISCV64:
|
||||
*subsystem = nt->nt64.OptionalHeader.Subsystem;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
#ifndef EM_AARCH64
|
||||
#define EM_AARCH64 183
|
||||
#endif
|
||||
#ifndef EM_RISCV
|
||||
#define EM_RISCV 243
|
||||
#endif
|
||||
#ifndef EM_LOONGARCH
|
||||
#define EM_LOONGARCH 258
|
||||
#endif
|
||||
@@ -167,6 +170,45 @@
|
||||
#ifndef R_LARCH_PCREL20_S2
|
||||
#define R_LARCH_PCREL20_S2 103
|
||||
#endif
|
||||
#ifndef R_RISCV_NONE
|
||||
#define R_RISCV_NONE 0
|
||||
#endif
|
||||
#ifndef R_RISCV_32
|
||||
#define R_RISCV_32 1
|
||||
#endif
|
||||
#ifndef R_RISCV_64
|
||||
#define R_RISCV_64 2
|
||||
#endif
|
||||
#ifndef R_RISCV_BRANCH
|
||||
#define R_RISCV_BRANCH 16
|
||||
#endif
|
||||
#ifndef R_RISCV_JAL
|
||||
#define R_RISCV_JAL 17
|
||||
#endif
|
||||
#ifndef R_RISCV_PCREL_HI20
|
||||
#define R_RISCV_PCREL_HI20 23
|
||||
#endif
|
||||
#ifndef R_RISCV_PCREL_LO12_I
|
||||
#define R_RISCV_PCREL_LO12_I 24
|
||||
#endif
|
||||
#ifndef R_RISCV_PCREL_LO12_S
|
||||
#define R_RISCV_PCREL_LO12_S 25
|
||||
#endif
|
||||
#ifndef R_RISCV_ADD32
|
||||
#define R_RISCV_ADD32 35
|
||||
#endif
|
||||
#ifndef R_RISCV_SUB32
|
||||
#define R_RISCV_SUB32 39
|
||||
#endif
|
||||
#ifndef R_RISCV_RVC_BRANCH
|
||||
#define R_RISCV_RVC_BRANCH 44
|
||||
#endif
|
||||
#ifndef R_RISCV_RVC_JUMP
|
||||
#define R_RISCV_RVC_JUMP 45
|
||||
#endif
|
||||
#ifndef R_RISCV_RELAX
|
||||
#define R_RISCV_RELAX 51
|
||||
#endif
|
||||
#ifndef R_X86_64_GOTPCRELX
|
||||
#define R_X86_64_GOTPCRELX 41
|
||||
#endif
|
||||
@@ -596,6 +638,11 @@ static void set_machine ( struct elf_file *elf, struct pe_header *pe_header ) {
|
||||
case EM_LOONGARCH:
|
||||
machine = EFI_IMAGE_MACHINE_LOONGARCH64;
|
||||
break;
|
||||
case EM_RISCV:
|
||||
machine = ( ( ELFCLASS == ELFCLASS64 ) ?
|
||||
EFI_IMAGE_MACHINE_RISCV64 :
|
||||
EFI_IMAGE_MACHINE_RISCV32 );
|
||||
break;
|
||||
default:
|
||||
eprintf ( "Unknown ELF architecture %d\n", ehdr->e_machine );
|
||||
exit ( 1 );
|
||||
@@ -828,16 +875,19 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
|
||||
case ELF_MREL ( EM_AARCH64, R_AARCH64_NONE ) :
|
||||
case ELF_MREL ( EM_AARCH64, R_AARCH64_NULL ) :
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_NONE ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_NONE ) :
|
||||
/* Ignore dummy relocations used by REQUIRE_SYMBOL() */
|
||||
break;
|
||||
case ELF_MREL ( EM_386, R_386_32 ) :
|
||||
case ELF_MREL ( EM_ARM, R_ARM_ABS32 ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_32 ) :
|
||||
/* Generate a 4-byte PE relocation */
|
||||
generate_pe_reloc ( pe_reltab, offset, 4 );
|
||||
break;
|
||||
case ELF_MREL ( EM_X86_64, R_X86_64_64 ) :
|
||||
case ELF_MREL ( EM_AARCH64, R_AARCH64_ABS64 ) :
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_64 ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_64 ) :
|
||||
/* Generate an 8-byte PE relocation */
|
||||
generate_pe_reloc ( pe_reltab, offset, 8 );
|
||||
break;
|
||||
@@ -869,16 +919,31 @@ static void process_reloc ( struct elf_file *elf, const Elf_Shdr *shdr,
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_HI20 ):
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_GOT_PC_LO12 ):
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_PCREL20_S2 ):
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_BRANCH ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_JAL ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_HI20 ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_LO12_I ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_PCREL_LO12_S ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_RVC_BRANCH ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_RVC_JUMP ) :
|
||||
/* Skip PC-relative relocations; all relative
|
||||
* offsets remain unaltered when the object is
|
||||
* loaded.
|
||||
*/
|
||||
break;
|
||||
case ELF_MREL ( EM_LOONGARCH, R_LARCH_RELAX ):
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_RELAX ) :
|
||||
/* Relocation can be relaxed (optimized out).
|
||||
* Ignore it for now.
|
||||
*/
|
||||
break;
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_ADD32 ) :
|
||||
case ELF_MREL ( EM_RISCV, R_RISCV_SUB32 ) :
|
||||
/* Ignore label difference relocations since
|
||||
* we do not perform any relocations that can
|
||||
* result in altered label differences.
|
||||
*/
|
||||
break;
|
||||
case ELF_MREL ( EM_X86_64, R_X86_64_32 ) :
|
||||
/* Ignore 32-bit relocations in a hybrid
|
||||
* 32-bit BIOS and 64-bit UEFI binary,
|
||||
|
||||
@@ -78,6 +78,12 @@ efi_boot_name() {
|
||||
"64aa" )
|
||||
echo "BOOTAA64.EFI"
|
||||
;;
|
||||
"6450" )
|
||||
echo "BOOTRISCV64.EFI"
|
||||
;;
|
||||
"3250" )
|
||||
echo "BOOTRISCV32.EFI"
|
||||
;;
|
||||
* )
|
||||
echo "${FILENAME}: unrecognised EFI architecture ${ARCH}" >&2
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user