diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-09-15 10:54:04 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-09-15 22:34:10 +0100 |
commit | c215048ddaac75969c22c018871295a5748a47e8 (patch) | |
tree | 1e47dce485579135c16c130778a810aaeb912d9c /src/util | |
parent | 68db9a3cb3d73aae83ee4b7a0cbe9c69d7f32482 (diff) | |
download | ipxe-c215048ddaac75969c22c018871295a5748a47e8.tar.gz |
[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>
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/efirom.c | 2 | ||||
-rw-r--r-- | src/util/elf2efi.c | 65 | ||||
-rwxr-xr-x | src/util/genfsimg | 6 |
3 files changed, 73 insertions, 0 deletions
diff --git a/src/util/efirom.c b/src/util/efirom.c index b0334bdb1..1220c187a 100644 --- a/src/util/efirom.c +++ b/src/util/efirom.c @@ -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: diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c index 4af587d87..5434e7040 100644 --- a/src/util/elf2efi.c +++ b/src/util/elf2efi.c @@ -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, diff --git a/src/util/genfsimg b/src/util/genfsimg index a981a62d8..23d191692 100755 --- a/src/util/genfsimg +++ b/src/util/genfsimg @@ -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 |