aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/riscv64
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/arch/riscv64
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/arch/riscv64')
-rw-r--r--src/arch/riscv64/Makefile19
-rw-r--r--src/arch/riscv64/Makefile.efi14
-rw-r--r--src/arch/riscv64/Makefile.linux10
-rw-r--r--src/arch/riscv64/core/riscv64_byteswap.S64
-rw-r--r--src/arch/riscv64/include/bits/profile.h28
-rw-r--r--src/arch/riscv64/include/ipxe/efi/dhcparch.h20
-rw-r--r--src/arch/riscv64/include/limits.h61
7 files changed, 216 insertions, 0 deletions
diff --git a/src/arch/riscv64/Makefile b/src/arch/riscv64/Makefile
new file mode 100644
index 000000000..2fd18fc13
--- /dev/null
+++ b/src/arch/riscv64/Makefile
@@ -0,0 +1,19 @@
+# RISCV64-specific directories containing source files
+#
+SRCDIRS += arch/riscv64/core
+
+# RISCV64-specific flags
+#
+CFLAGS += -march=rv64gc -mabi=lp64d
+ASFLAGS += -march=rv64gc -mabi=lp64d
+LDFLAGS += -m elf64lriscv
+
+# Include common RISCV Makefile
+#
+MAKEDEPS += arch/riscv/Makefile
+include arch/riscv/Makefile
+
+# Include platform-specific Makefile
+#
+MAKEDEPS += arch/riscv64/Makefile.$(PLATFORM)
+include arch/riscv64/Makefile.$(PLATFORM)
diff --git a/src/arch/riscv64/Makefile.efi b/src/arch/riscv64/Makefile.efi
new file mode 100644
index 000000000..b19e036a3
--- /dev/null
+++ b/src/arch/riscv64/Makefile.efi
@@ -0,0 +1,14 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# Specify EFI image builder
+#
+ELF2EFI = $(ELF2EFI64)
+
+# Specify EFI boot file
+#
+EFI_BOOT_FILE = bootriscv64.efi
+
+# Include generic EFI Makefile
+#
+MAKEDEPS += arch/riscv/Makefile.efi
+include arch/riscv/Makefile.efi
diff --git a/src/arch/riscv64/Makefile.linux b/src/arch/riscv64/Makefile.linux
new file mode 100644
index 000000000..5ceafed8c
--- /dev/null
+++ b/src/arch/riscv64/Makefile.linux
@@ -0,0 +1,10 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# Starting virtual address
+#
+LDFLAGS += -Ttext=0x10000
+
+# Include generic Linux Makefile
+#
+MAKEDEPS += arch/riscv/Makefile.linux
+include arch/riscv/Makefile.linux
diff --git a/src/arch/riscv64/core/riscv64_byteswap.S b/src/arch/riscv64/core/riscv64_byteswap.S
new file mode 100644
index 000000000..ec2b0b9dd
--- /dev/null
+++ b/src/arch/riscv64/core/riscv64_byteswap.S
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+/** @file
+ *
+ * Byte swapping
+ *
+ */
+
+ .section ".note.GNU-stack", "", @progbits
+ .text
+
+ .section ".text.riscv_swap", "ax", @progbits
+riscv_swap:
+ .globl riscv_swap_word
+ .globl riscv_swap_half
+ .globl riscv_swap_byte
+riscv_swap_word:
+ /* Swap low and high words of a0 */
+ slli t0, a0, 32
+ srli a0, a0, 32
+ or a0, a0, t0
+riscv_swap_half:
+ /* Swap half-words within each word of a0 */
+ ld t1, mask16
+ slli t2, a0, 16
+ and a0, a0, t1
+ and t2, t2, t1
+ srli a0, a0, 16
+ or a0, a0, t2
+riscv_swap_byte:
+ /* Swap bytes within each half-word of a0 */
+ ld t3, mask8
+ slli t4, a0, 8
+ and a0, a0, t3
+ and t4, t4, t3
+ srli a0, a0, 8
+ or a0, a0, t4
+ ret
+mask16: .dword 0xffff0000ffff0000
+mask8: .dword 0xff00ff00ff00ff00
+ .size riscv_swap, . - riscv_swap
diff --git a/src/arch/riscv64/include/bits/profile.h b/src/arch/riscv64/include/bits/profile.h
new file mode 100644
index 000000000..2c8e29a22
--- /dev/null
+++ b/src/arch/riscv64/include/bits/profile.h
@@ -0,0 +1,28 @@
+#ifndef _BITS_PROFILE_H
+#define _BITS_PROFILE_H
+
+/** @file
+ *
+ * Profiling
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+
+/**
+ * Get profiling timestamp
+ *
+ * @ret timestamp Timestamp
+ */
+static inline __attribute__ (( always_inline )) uint64_t
+profile_timestamp ( void ) {
+ uint64_t cycles;
+
+ /* Read timestamp counter */
+ __asm__ __volatile__ ( "rdcycle %0" : "=r" ( cycles ) );
+ return cycles;
+}
+
+#endif /* _BITS_PROFILE_H */
diff --git a/src/arch/riscv64/include/ipxe/efi/dhcparch.h b/src/arch/riscv64/include/ipxe/efi/dhcparch.h
new file mode 100644
index 000000000..33bca044e
--- /dev/null
+++ b/src/arch/riscv64/include/ipxe/efi/dhcparch.h
@@ -0,0 +1,20 @@
+#ifndef _IPXE_EFI_DHCPARCH_H
+#define _IPXE_EFI_DHCPARCH_H
+
+/** @file
+ *
+ * DHCP client architecture definitions
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/dhcp.h>
+
+/** DHCP client architecture */
+#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_RISCV64
+
+/** DHCP client network device interface */
+#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
+
+#endif /* _IPXE_EFI_DHCPARCH_H */
diff --git a/src/arch/riscv64/include/limits.h b/src/arch/riscv64/include/limits.h
new file mode 100644
index 000000000..a1374a17f
--- /dev/null
+++ b/src/arch/riscv64/include/limits.h
@@ -0,0 +1,61 @@
+#ifndef LIMITS_H
+#define LIMITS_H 1
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/* Number of bits in a `char' */
+#define CHAR_BIT 8
+
+/* Minimum and maximum values a `signed char' can hold */
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+
+/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
+#define UCHAR_MAX 255
+
+/* Minimum and maximum values a `char' can hold */
+#define CHAR_MIN SCHAR_MIN
+#define CHAR_MAX SCHAR_MAX
+
+/* Minimum and maximum values a `signed short int' can hold */
+#define SHRT_MIN (-32768)
+#define SHRT_MAX 32767
+
+/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
+#define USHRT_MAX 65535
+
+
+/* Minimum and maximum values a `signed int' can hold */
+#define INT_MIN (-INT_MAX - 1)
+#define INT_MAX 2147483647
+
+/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
+#define UINT_MAX 4294967295U
+
+
+/* Minimum and maximum values a `signed int' can hold */
+#define INT_MAX 2147483647
+#define INT_MIN (-INT_MAX - 1)
+
+
+/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
+#define UINT_MAX 4294967295U
+
+
+/* Minimum and maximum values a `signed long' can hold */
+#define LONG_MAX 9223372036854775807L
+#define LONG_MIN (-LONG_MAX - 1L)
+
+/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
+#define ULONG_MAX 18446744073709551615UL
+
+/* Minimum and maximum values a `signed long long' can hold */
+#define LLONG_MAX 9223372036854775807LL
+#define LLONG_MIN (-LONG_MAX - 1LL)
+
+
+/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
+#define ULLONG_MAX 18446744073709551615ULL
+
+
+#endif /* LIMITS_H */