arch/risc-v/src/mpfs: Make each hart entry configurable for bootloader

Add two config flags for each hart for a bootloader nuttx:

CONFIG_MPFS_HARTx_SBI :
- select whether the hart boots via opensbi or not.

CONFIG_MPFS_HARTx_ENTRYPOINT :
- the target address to jump to, either directly from startup code or
  from SBI if CONFIG_MPFS_HARTx_SBI is set

This allows building a nuttx based bootloader application, which can load
different applications/OSs for individual harts and jump to those

Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
Jukka Laitinen 2022-01-12 08:21:26 +02:00 committed by Xiang Xiao
parent 36b73fd0a3
commit 9061c92ec8
4 changed files with 133 additions and 25 deletions

View File

@ -58,6 +58,66 @@ config MPFS_OPENSBI
---help---
This uses a ld-envm-opensbi.script linker script and the mpfs_opensbi.c code to use external OpenSBI.
config MPFS_HART0_SBI
bool "HART0 boots via SBI"
depends on MPFS_OPENSBI
default n
config MPFS_HART1_SBI
bool "HART1 boots via SBI"
depends on MPFS_OPENSBI
default n
config MPFS_HART2_SBI
bool "HART2 boots via SBI"
depends on MPFS_OPENSBI
default n
config MPFS_HART3_SBI
bool "HART3 boots via SBI"
depends on MPFS_OPENSBI
default n
config MPFS_HART4_SBI
bool "HART4 boots via SBI"
depends on MPFS_OPENSBI
default n
config MPFS_HART0_ENTRYPOINT
hex "Application entry point for HART0"
depends on MPFS_BOOTLOADER
default 0xffffffffffffffff
---help---
The default address of the entry point for HART0
config MPFS_HART1_ENTRYPOINT
hex "Application entry point for HART1"
depends on MPFS_BOOTLOADER
default 0xffffffffffffffff
---help---
The default address of the entry point for HART1
config MPFS_HART2_ENTRYPOINT
hex "Application entry point for HART2"
depends on MPFS_BOOTLOADER
default 0xafb00000
---help---
The default address of the entry point for HART2
config MPFS_HART3_ENTRYPOINT
hex "Application entry point for HART3"
depends on MPFS_BOOTLOADER
default 0xffffffffffffffff
---help---
The default address of the entry point for HART3
config MPFS_HART4_ENTRYPOINT
hex "Application entry point for HART4"
depends on MPFS_BOOTLOADER
default 0xffffffffffffffff
---help---
The default address of the entry point for HART4
config MPFS_BOOT_HART
int "HART used for booting"
depends on MPFS_BOOTLOADER

View File

@ -133,6 +133,18 @@ __start:
.skip_e51:
/* initialize global pointer, global data
* The __global_pointer is allocated in the linker script.
* It points to a location between _sdata and _edata as the offsets used in the gp are +/- 2k
* See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
* see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
*/
.option push
.option norelax
la gp, __global_pointer$
.option pop
#ifdef CONFIG_MPFS_BOOTLOADER
/* Set all but the boot hart into wfi */
@ -166,13 +178,17 @@ __start:
csrw mie, zero
csrw mip, zero
#ifdef CONFIG_MPFS_OPENSBI
jal mpfs_opensbi_prepare_hart
#else
/* Jump to app (TODO: remove fixed address) */
li a1, 0x80000000
jr a1
#endif
/* Offset to g_entrypoints vector, acc. to hart id */
li t1,8
mul t1, a0, t1
/* Load the entrypoint address */
la t0, g_entrypoints
add t0, t0, t1
ld t0, 0(t0)
/* Jump to app */
jr t0
.continue_boot:
@ -182,20 +198,6 @@ __start:
la sp, MPFS_IDLESTACK_TOP
/* initialize global pointer, global data
* The __global_pointer is allocated in the linker script.
* It points to a location between _sdata and _edata as the offsets used in the gp are +/- 2k
* See https://www.sifive.com/blog/2017/08/28/all-aboard-part-3-linker-relaxation-in-riscv-toolchain/
* see: http://www.rowleydownload.co.uk/arm/documentation/gnu/as/RISC_002dV_002dDirectives.html
*/
.option push
.option norelax
la gp, __global_pointer$
.option pop
/* Jump to __mpfs_start with mhartid in a0 */
jal __mpfs_start

View File

@ -71,8 +71,6 @@
#define MPFS_PMP_DEFAULT_ADDR 0xfffffffff
#define MPFS_PMP_DEFAULT_PERM 0x000000009f
#define UBOOT_LOAD_ADDR 0x80200000 /* We expect u-boot here */
/* The following define is not accessible with assember. Make sure it's in
* sync with the assembler usage in mpfs_opensbi_utils.S.
*/
@ -215,6 +213,15 @@ uint8_t g_hart_stacks[SBI_PLATFORM_DEFAULT_HART_STACK_SIZE * \
MPFS_HART_COUNT] \
__attribute__((section(".ddrstorage"), aligned(16)));
static const uint64_t sbi_entrypoints[] =
{
CONFIG_MPFS_HART0_ENTRYPOINT,
CONFIG_MPFS_HART1_ENTRYPOINT,
CONFIG_MPFS_HART2_ENTRYPOINT,
CONFIG_MPFS_HART3_ENTRYPOINT,
CONFIG_MPFS_HART4_ENTRYPOINT
};
/****************************************************************************
* Private Functions
****************************************************************************/
@ -533,7 +540,7 @@ void __attribute__((noreturn)) mpfs_opensbi_setup(void)
csr_write(mscratch, &g_scratches[hartid].scratch);
g_scratches[hartid].scratch.next_mode = PRV_S;
g_scratches[hartid].scratch.next_addr = UBOOT_LOAD_ADDR;
g_scratches[hartid].scratch.next_addr = sbi_entrypoints[hartid];
g_scratches[hartid].scratch.next_arg1 = 0;
sbi_init(&g_scratches[hartid].scratch);

View File

@ -63,7 +63,46 @@
uintptr_t g_idle_topstack = MPFS_IDLESTACK_TOP;
volatile bool g_serial_ok = false;
extern void mpfs_cpu_boot(uint32_t);
/* Default boot address for every hart */
#ifdef CONFIG_MPFS_BOOTLOADER
extern void mpfs_opensbi_prepare_hart(void);
const uint64_t g_entrypoints[5] =
{
#ifdef CONFIG_MPFS_HART0_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
CONFIG_MPFS_HART0_ENTRYPOINT,
#endif
#ifdef CONFIG_MPFS_HART1_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
CONFIG_MPFS_HART1_ENTRYPOINT,
#endif
#ifdef CONFIG_MPFS_HART2_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
CONFIG_MPFS_HART2_ENTRYPOINT,
#endif
#ifdef CONFIG_MPFS_HART3_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
CONFIG_MPFS_HART3_ENTRYPOINT,
#endif
#ifdef CONFIG_MPFS_HART4_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
CONFIG_MPFS_HART4_ENTRYPOINT,
#endif
};
#endif
/****************************************************************************
* Public Functions