riscv: Add initial support for 32bit boards
* Adding separate targets for 32bit and 64bit qemu * Using the riscv64 toolchain for 32bit builds requires setting -m elf32lriscv * rv32/rv64 is currently configured with ARCH_RISCV_RV32/RV64 and not per stage. This should probably be changed later. TEST=Boots to "Payload not loaded." on 32bit qemu using the following commands: util/riscv/make-spike-elf.sh build/coreboot.rom build/coreboot.elf qemu-system-riscv32 -M virt -m 1024M -nographic -kernel build/coreboot.elf Change-Id: I35e59b459d1770df10b51fe9e77dcc474d7c75a0 Signed-off-by: Philipp Hug <philipp@hug.cx> Reviewed-on: https://review.coreboot.org/c/31253 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: ron minnich <rminnich@gmail.com>
This commit is contained in:
		@@ -86,6 +86,10 @@ $(objcbfs)/bootblock.debug: $$(bootblock-objs)
 | 
				
			|||||||
bootblock-c-ccopts += $(riscv_flags)
 | 
					bootblock-c-ccopts += $(riscv_flags)
 | 
				
			||||||
bootblock-S-ccopts += $(riscv_asm_flags)
 | 
					bootblock-S-ccopts += $(riscv_asm_flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_ARCH_RISCV_RV32),y)
 | 
				
			||||||
 | 
					LDFLAGS_bootblock += -m elf32lriscv
 | 
				
			||||||
 | 
					endif #CONFIG_ARCH_RISCV_RV32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif #CONFIG_ARCH_BOOTBLOCK_RISCV
 | 
					endif #CONFIG_ARCH_BOOTBLOCK_RISCV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
@@ -116,6 +120,10 @@ $(objcbfs)/romstage.debug: $$(romstage-objs)
 | 
				
			|||||||
romstage-c-ccopts += $(riscv_flags)
 | 
					romstage-c-ccopts += $(riscv_flags)
 | 
				
			||||||
romstage-S-ccopts += $(riscv_asm_flags)
 | 
					romstage-S-ccopts += $(riscv_asm_flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_ARCH_RISCV_RV32),y)
 | 
				
			||||||
 | 
					LDFLAGS_romstage += -m elf32lriscv
 | 
				
			||||||
 | 
					endif #CONFIG_ARCH_RISCV_RV32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif #CONFIG_ARCH_ROMSTAGE_RISCV
 | 
					endif #CONFIG_ARCH_ROMSTAGE_RISCV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
################################################################################
 | 
					################################################################################
 | 
				
			||||||
@@ -161,5 +169,9 @@ $(objcbfs)/ramstage.debug: $$(ramstage-objs)
 | 
				
			|||||||
ramstage-c-ccopts += $(riscv_flags)
 | 
					ramstage-c-ccopts += $(riscv_flags)
 | 
				
			||||||
ramstage-S-ccopts += $(riscv_asm_flags)
 | 
					ramstage-S-ccopts += $(riscv_asm_flags)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_ARCH_RISCV_RV32),y)
 | 
				
			||||||
 | 
					LDFLAGS_ramstage += -m elf32lriscv
 | 
				
			||||||
 | 
					endif #CONFIG_ARCH_RISCV_RV32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif #CONFIG_ARCH_RAMSTAGE_RISCV
 | 
					endif #CONFIG_ARCH_RAMSTAGE_RISCV
 | 
				
			||||||
endif #CONFIG_ARCH_RISCV
 | 
					endif #CONFIG_ARCH_RISCV
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <arch/encoding.h>
 | 
					#include <arch/encoding.h>
 | 
				
			||||||
 | 
					#include <bits.h>
 | 
				
			||||||
#include <mcall.h>
 | 
					#include <mcall.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.section ".text._start", "ax", %progbits
 | 
					.section ".text._start", "ax", %progbits
 | 
				
			||||||
@@ -44,7 +45,7 @@ _start:
 | 
				
			|||||||
	slli t1, a0, RISCV_PGSHIFT
 | 
						slli t1, a0, RISCV_PGSHIFT
 | 
				
			||||||
	add  t0, t0, t1
 | 
						add  t0, t0, t1
 | 
				
			||||||
	li   t1, 0xDEADBEEF
 | 
						li   t1, 0xDEADBEEF
 | 
				
			||||||
	sd   t1, 0(t0)
 | 
						STORE t1, 0(t0)
 | 
				
			||||||
	li   t1, RISCV_PGSIZE - HLS_SIZE
 | 
						li   t1, RISCV_PGSIZE - HLS_SIZE
 | 
				
			||||||
	add  sp, t0, t1
 | 
						add  sp, t0, t1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@
 | 
				
			|||||||
#define barrier() { asm volatile ("fence" ::: "memory"); }
 | 
					#define barrier() { asm volatile ("fence" ::: "memory"); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	volatile atomic_t lock;
 | 
						atomic_t lock;
 | 
				
			||||||
} spinlock_t;
 | 
					} spinlock_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void spinlock_lock(spinlock_t *lock)
 | 
					static inline void spinlock_lock(spinlock_t *lock)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,10 +47,19 @@
 | 
				
			|||||||
#define STR(x) XSTR(x)
 | 
					#define STR(x) XSTR(x)
 | 
				
			||||||
#define XSTR(x) #x
 | 
					#define XSTR(x) #x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# define SLL32    sllw
 | 
					#if __riscv_xlen == 64
 | 
				
			||||||
# define STORE    sd
 | 
					#define SLL32 sllw
 | 
				
			||||||
# define LOAD     ld
 | 
					#define STORE sd
 | 
				
			||||||
# define LOG_REGBYTES 3
 | 
					#define LOAD ld
 | 
				
			||||||
 | 
					#define LWU lwu
 | 
				
			||||||
 | 
					#define LOG_REGBYTES 3
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define SLL32 sll
 | 
				
			||||||
 | 
					#define STORE sw
 | 
				
			||||||
 | 
					#define LOAD lw
 | 
				
			||||||
 | 
					#define LWU lw
 | 
				
			||||||
 | 
					#define LOG_REGBYTES 2
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REGBYTES (1 << LOG_REGBYTES)
 | 
					#define REGBYTES (1 << LOG_REGBYTES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NOTE: this is the size of hls_t below. A static_assert would be
 | 
					// NOTE: this is the size of hls_t below. A static_assert would be
 | 
				
			||||||
// nice to have.
 | 
					// nice to have.
 | 
				
			||||||
 | 
					#if __riscv_xlen == 64
 | 
				
			||||||
#define HLS_SIZE 88
 | 
					#define HLS_SIZE 88
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __riscv_xlen == 32
 | 
				
			||||||
 | 
					#define HLS_SIZE 52
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* We save 37 registers, currently. */
 | 
					/* We save 37 registers, currently. */
 | 
				
			||||||
#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * 8)
 | 
					#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * 8)
 | 
				
			||||||
@@ -26,6 +32,7 @@
 | 
				
			|||||||
#ifndef __ASSEMBLER__
 | 
					#ifndef __ASSEMBLER__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <arch/encoding.h>
 | 
					#include <arch/encoding.h>
 | 
				
			||||||
 | 
					#include <arch/smp/atomic.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
@@ -38,8 +45,8 @@ typedef struct {
 | 
				
			|||||||
struct blocker {
 | 
					struct blocker {
 | 
				
			||||||
	void *arg;
 | 
						void *arg;
 | 
				
			||||||
	void (*fn)(void *arg);
 | 
						void (*fn)(void *arg);
 | 
				
			||||||
	uint32_t sync_a;
 | 
						atomic_t sync_a;
 | 
				
			||||||
	uint32_t sync_b;
 | 
						atomic_t sync_b;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <arch/encoding.h>
 | 
					#include <arch/encoding.h>
 | 
				
			||||||
 | 
					#include <bits.h>
 | 
				
			||||||
#include <mcall.h>
 | 
					#include <mcall.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.section ".text._start", "ax", %progbits
 | 
					.section ".text._start", "ax", %progbits
 | 
				
			||||||
@@ -27,7 +28,7 @@ _start:
 | 
				
			|||||||
	slli t1, a0, RISCV_PGSHIFT
 | 
						slli t1, a0, RISCV_PGSHIFT
 | 
				
			||||||
	add  t0, t0, t1
 | 
						add  t0, t0, t1
 | 
				
			||||||
	li   t1, 0xDEADBEEF
 | 
						li   t1, 0xDEADBEEF
 | 
				
			||||||
	sd   t1, 0(t0)
 | 
						STORE t1, 0(t0)
 | 
				
			||||||
	li   t1, RISCV_PGSIZE - HLS_SIZE
 | 
						li   t1, RISCV_PGSIZE - HLS_SIZE
 | 
				
			||||||
	add  sp, t0, t1
 | 
						add  sp, t0, t1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,13 +32,13 @@ void smp_pause(int working_hartid)
 | 
				
			|||||||
		/* waiting for work hart */
 | 
							/* waiting for work hart */
 | 
				
			||||||
		do {
 | 
							do {
 | 
				
			||||||
			barrier();
 | 
								barrier();
 | 
				
			||||||
		} while (SYNCA != 0x01234567);
 | 
							} while (atomic_read(&SYNCA) != 0x01234567);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		clear_csr(mstatus, MSTATUS_MIE);
 | 
							clear_csr(mstatus, MSTATUS_MIE);
 | 
				
			||||||
		write_csr(mie, MIP_MSIP);
 | 
							write_csr(mie, MIP_MSIP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* count how many cores enter the halt */
 | 
							/* count how many cores enter the halt */
 | 
				
			||||||
		__sync_fetch_and_add(&SYNCB, 1);
 | 
							atomic_add(&SYNCB, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		do {
 | 
							do {
 | 
				
			||||||
			barrier();
 | 
								barrier();
 | 
				
			||||||
@@ -49,17 +49,17 @@ void smp_pause(int working_hartid)
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		/* Initialize the counter and
 | 
							/* Initialize the counter and
 | 
				
			||||||
		 * mark the work hart into smp_pause */
 | 
							 * mark the work hart into smp_pause */
 | 
				
			||||||
		SYNCB = 0;
 | 
							atomic_set(&SYNCB, 0);
 | 
				
			||||||
		SYNCA = 0x01234567;
 | 
							atomic_set(&SYNCA, 0x01234567);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* waiting for other Hart to enter the halt */
 | 
							/* waiting for other Hart to enter the halt */
 | 
				
			||||||
		do {
 | 
							do {
 | 
				
			||||||
			barrier();
 | 
								barrier();
 | 
				
			||||||
		} while (SYNCB + 1 < CONFIG_MAX_CPUS);
 | 
							} while (atomic_read(&SYNCB) + 1 < CONFIG_MAX_CPUS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* initialize for the next call */
 | 
							/* initialize for the next call */
 | 
				
			||||||
		SYNCA = 0;
 | 
							atomic_set(&SYNCA, 0);
 | 
				
			||||||
		SYNCB = 0;
 | 
							atomic_set(&SYNCB, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#undef SYNCA
 | 
					#undef SYNCA
 | 
				
			||||||
#undef SYNCB
 | 
					#undef SYNCB
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,8 @@
 | 
				
			|||||||
 * <lib.h> in case GCC does not have an assembly version for this arch.
 | 
					 * <lib.h> in case GCC does not have an assembly version for this arch.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !IS_ENABLED(CONFIG_ARCH_X86) /* work around lack of --gc-sections on x86 */
 | 
					#if !IS_ENABLED(CONFIG_ARCH_X86)	       /* work around lack of --gc-sections on x86 */ \
 | 
				
			||||||
 | 
						&& !IS_ENABLED(CONFIG_ARCH_RISCV_RV32) /* defined in rv32 libgcc.a */
 | 
				
			||||||
int __clzsi2(u32 a);
 | 
					int __clzsi2(u32 a);
 | 
				
			||||||
int __clzsi2(u32 a)
 | 
					int __clzsi2(u32 a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,21 @@
 | 
				
			|||||||
# util/riscv/make-spike-elf.sh build/coreboot.rom build/coreboot.elf
 | 
					# util/riscv/make-spike-elf.sh build/coreboot.rom build/coreboot.elf
 | 
				
			||||||
# qemu-system-riscv64 -M virt -m 1024M -nographic -kernel build/coreboot.elf
 | 
					# qemu-system-riscv64 -M virt -m 1024M -nographic -kernel build/coreboot.elf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if BOARD_EMULATION_QEMU_RISCV_RV64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config BOARD_EMULATION_QEMU_RISCV
 | 
				
			||||||
 | 
						def_bool y
 | 
				
			||||||
 | 
						select ARCH_RISCV_RV64
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if BOARD_EMULATION_QEMU_RISCV_RV32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config BOARD_EMULATION_QEMU_RISCV
 | 
				
			||||||
 | 
						def_bool y
 | 
				
			||||||
 | 
						select ARCH_RISCV_RV32
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if BOARD_EMULATION_QEMU_RISCV
 | 
					if BOARD_EMULATION_QEMU_RISCV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config BOARD_SPECIFIC_OPTIONS
 | 
					config BOARD_SPECIFIC_OPTIONS
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,5 @@
 | 
				
			|||||||
config BOARD_EMULATION_QEMU_RISCV
 | 
					config BOARD_EMULATION_QEMU_RISCV_RV64
 | 
				
			||||||
	bool "QEMU riscv"
 | 
						bool "QEMU RISC-V rv64"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config BOARD_EMULATION_QEMU_RISCV_RV32
 | 
				
			||||||
 | 
						bool "QEMU RISC-V rv32"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ if BOARD_EMULATION_SPIKE_RISCV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
config BOARD_SPECIFIC_OPTIONS
 | 
					config BOARD_SPECIFIC_OPTIONS
 | 
				
			||||||
	def_bool y
 | 
						def_bool y
 | 
				
			||||||
 | 
						select ARCH_RISCV_RV64
 | 
				
			||||||
	select SOC_UCB_RISCV
 | 
						select SOC_UCB_RISCV
 | 
				
			||||||
	select BOARD_ROMSIZE_KB_4096
 | 
						select BOARD_ROMSIZE_KB_4096
 | 
				
			||||||
	select DRIVERS_UART_8250MEM
 | 
						select DRIVERS_UART_8250MEM
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
config SOC_UCB_RISCV
 | 
					config SOC_UCB_RISCV
 | 
				
			||||||
	select ARCH_RISCV_RV64
 | 
					 | 
				
			||||||
	select ARCH_RISCV_S
 | 
						select ARCH_RISCV_S
 | 
				
			||||||
	select ARCH_RISCV_U
 | 
						select ARCH_RISCV_U
 | 
				
			||||||
	select ARCH_RISCV_PMP
 | 
						select ARCH_RISCV_PMP
 | 
				
			||||||
@@ -15,6 +14,8 @@ config SOC_UCB_RISCV
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
if SOC_UCB_RISCV
 | 
					if SOC_UCB_RISCV
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ARCH_RISCV_RV64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config RISCV_ARCH
 | 
					config RISCV_ARCH
 | 
				
			||||||
	string
 | 
						string
 | 
				
			||||||
	default "rv64imafd"
 | 
						default "rv64imafd"
 | 
				
			||||||
@@ -27,6 +28,24 @@ config RISCV_CODEMODEL
 | 
				
			|||||||
	string
 | 
						string
 | 
				
			||||||
	default "medany"
 | 
						default "medany"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ARCH_RISCV_RV32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config RISCV_ARCH
 | 
				
			||||||
 | 
						string
 | 
				
			||||||
 | 
						default "rv32im"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config RISCV_ABI
 | 
				
			||||||
 | 
						string
 | 
				
			||||||
 | 
						default "ilp32"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config RISCV_CODEMODEL
 | 
				
			||||||
 | 
						string
 | 
				
			||||||
 | 
						default "medany"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config RISCV_WORKING_HARTID
 | 
					config RISCV_WORKING_HARTID
 | 
				
			||||||
	int
 | 
						int
 | 
				
			||||||
	default 0
 | 
						default 0
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user