[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:
Michael Brown
2024-09-15 10:54:04 +01:00
parent 68db9a3cb3
commit c215048dda
42 changed files with 2405 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
# RISCV32-specific directories containing source files
#
SRCDIRS += arch/riscv32/core
SRCDIRS += arch/riscv32/libgcc
# RISCV32-specific flags
#
CFLAGS += -march=rv32gc -mabi=ilp32d
ASFLAGS += -march=rv32gc -mabi=ilp32d
LDFLAGS += -m elf32lriscv
# Include common RISCV Makefile
#
MAKEDEPS += arch/riscv/Makefile
include arch/riscv/Makefile
# Include platform-specific Makefile
#
MAKEDEPS += arch/riscv32/Makefile.$(PLATFORM)
include arch/riscv32/Makefile.$(PLATFORM)
+14
View File
@@ -0,0 +1,14 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Specify EFI image builder
#
ELF2EFI = $(ELF2EFI32)
# Specify EFI boot file
#
EFI_BOOT_FILE = bootriscv32.efi
# Include generic EFI Makefile
#
MAKEDEPS += arch/riscv/Makefile.efi
include arch/riscv/Makefile.efi
+14
View File
@@ -0,0 +1,14 @@
# -*- makefile -*- : Force emacs to use Makefile mode
# Starting virtual address
#
LDFLAGS += -Ttext=0x10000
# Compiler flags for building host API wrapper
#
LINUX_CFLAGS += -march=rv32gc -mabi=ilp32d
# Include generic Linux Makefile
#
MAKEDEPS += arch/riscv/Makefile.linux
include arch/riscv/Makefile.linux
+63
View File
@@ -0,0 +1,63 @@
/*
* 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 all bytes in a0 */
mv t0, ra
jal riscv_swap_half
mv ra, t0
/* Swap words a0 and a1 */
mv t1, a0
mv a0, a1
mv a1, t1
riscv_swap_half:
/* Swap half-words within a0 */
slli t2, a0, 16
srli a0, a0, 16
or a0, a0, t2
riscv_swap_byte:
/* Swap bytes within each half-word of a0 */
li t3, 0xff00ff00
slli t4, a0, 8
and a0, a0, t3
and t4, t4, t3
srli a0, a0, 8
or a0, a0, t4
ret
.size riscv_swap, . - riscv_swap
+36
View File
@@ -0,0 +1,36 @@
#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 ) {
uint32_t cycles_lo;
uint32_t cycles_hi;
uint32_t tmp;
/* Read timestamp counter */
__asm__ __volatile__ ( "\n1:\n\t"
"rdcycleh %1\n\t"
"rdcycle %0\n\t"
"rdcycleh %2\n\t"
"bne %1, %2, 1b\n\t"
: "=r" ( cycles_lo ), "=r" ( cycles_hi ),
"=r" ( tmp ) );
return ( ( ( ( uint64_t ) cycles_hi ) << 32 ) | cycles_lo );
}
#endif /* _BITS_PROFILE_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_RISCV32
/** DHCP client network device interface */
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
#endif /* _IPXE_EFI_DHCPARCH_H */
+61
View File
@@ -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 2147483647
#define LONG_MIN (-LONG_MAX - 1L)
/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
#define ULONG_MAX 4294967295UL
/* 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 */
+112
View File
@@ -0,0 +1,112 @@
/*
* 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
*
* Long shifts
*
*/
.section ".note.GNU-stack", "", @progbits
.text
/**
* Shift left
*
* @v a1:a0 Value to shift
* @v a2 Shift amount
* @ret a1:a0 Shifted value
*/
.section ".text.__ashldi3", "ax", @progbits
.globl __ashldi3
__ashldi3:
/* Perform shift by 32 bits, if applicable */
li t0, 32
sub t1, t0, a2
bgtz t1, 1f
mv a1, a0
mv a0, zero
1: /* Perform shift by modulo-32 bits, if applicable */
andi a2, a2, 0x1f
beqz a2, 2f
srl t2, a0, t1
sll a0, a0, a2
sll a1, a1, a2
or a1, a1, t2
2: ret
.size __ashldi3, . - __ashldi3
/**
* Logical shift right
*
* @v a1:a0 Value to shift
* @v a2 Shift amount
* @ret a1:a0 Shifted value
*/
.section ".text.__lshrdi3", "ax", @progbits
.globl __lshrdi3
__lshrdi3:
/* Perform shift by 32 bits, if applicable */
li t0, 32
sub t1, t0, a2
bgtz t1, 1f
mv a0, a1
mv a1, zero
1: /* Perform shift by modulo-32 bits, if applicable */
andi a2, a2, 0x1f
beqz a2, 2f
sll t2, a1, t1
srl a1, a1, a2
srl a0, a0, a2
or a0, a0, t2
2: ret
.size __lshrdi3, . - __lshrdi3
/**
* Arithmetic shift right
*
* @v a1:a0 Value to shift
* @v a2 Shift amount
* @ret a1:a0 Shifted value
*/
.section ".text.__ashrdi3", "ax", @progbits
.globl __ashrdi3
__ashrdi3:
/* Perform shift by 32 bits, if applicable */
li t0, 32
sub t1, t0, a2
bgtz t1, 1f
mv a0, a1
srai a1, a1, 16
srai a1, a1, 16
1: /* Perform shift by modulo-32 bits, if applicable */
andi a2, a2, 0x1f
beqz a2, 2f
sll t2, a1, t1
sra a1, a1, a2
srl a0, a0, a2
or a0, a0, t2
2: ret
.size __ashrdi3, . - __ashrdi3