[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

19
src/arch/riscv64/Makefile Normal file
View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

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 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 */