aboutsummaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-09-15 10:54:04 +0100
committerMichael Brown <mcb30@ipxe.org>2024-09-15 22:34:10 +0100
commitc215048ddaac75969c22c018871295a5748a47e8 (patch)
tree1e47dce485579135c16c130778a810aaeb912d9c /src/util
parent68db9a3cb3d73aae83ee4b7a0cbe9c69d7f32482 (diff)
downloadipxe-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.c2
-rw-r--r--src/util/elf2efi.c65
-rwxr-xr-xsrc/util/genfsimg6
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