arch/mpfs: Make selection of SBI boot or direct boot run-time configurable

Allow bootloader to select run-time whether the payload binary is booted with
SBI or directly by jumping to entrypoint address.

- Use just one bitmask to select sbi or direct boot for each hart
- Add mpfs_set_use_sbi function to allow selecting how to boot
- Initialize the bitmask by default according to the configuration flags
- Add a header file for including the function prototypes in bootloader code

Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
Jukka Laitinen 2023-01-17 22:05:00 +04:00 committed by Xiang Xiao
parent 931677a86e
commit e2a7cee5ed
3 changed files with 161 additions and 60 deletions

View File

@ -27,11 +27,18 @@
#ifdef CONFIG_MPFS_BOOTLOADER
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/compiler.h>
#include <sys/types.h>
/****************************************************************************
* Extern Function Declarations
****************************************************************************/
extern void mpfs_opensbi_prepare_hart(void);
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -53,71 +60,48 @@ static uint64_t g_app_entrypoints[] =
CONFIG_MPFS_HART4_ENTRYPOINT
};
/****************************************************************************
* Private Functions
****************************************************************************/
static void jump_to_app(void) naked_function;
static void jump_to_app(void)
{
__asm__ __volatile__
(
"csrr a0, mhartid\n" /* Hart ID */
"slli t1, a0, 3\n" /* To entrypoint offset */
"la t0, g_app_entrypoints\n" /* Entrypoint table base */
"add t0, t0, t1\n" /* Index in table */
"ld t0, 0(t0)\n" /* Load the address from table */
"jr t0" /* Jump to entrypoint */
);
}
/****************************************************************************
* Public Data
****************************************************************************/
/* Default boot address for every hart */
extern void mpfs_opensbi_prepare_hart(void);
/* Trampoline functions, jump to SBI if so configured, to app if not */
const uint64_t g_entrypoints[5] =
{
#ifdef CONFIG_MPFS_HART0_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
(uint64_t)jump_to_app,
#endif
static uint64_t g_hart_use_sbi =
#ifdef CONFIG_MPFS_HART1_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
(uint64_t)jump_to_app,
(1 << 1) |
#endif
#ifdef CONFIG_MPFS_HART2_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
(uint64_t)jump_to_app,
(1 << 2) |
#endif
#ifdef CONFIG_MPFS_HART3_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
(uint64_t)jump_to_app,
(1 << 3) |
#endif
#ifdef CONFIG_MPFS_HART4_SBI
(uint64_t)mpfs_opensbi_prepare_hart,
#else
(uint64_t)jump_to_app,
(1 << 4) |
#endif
};
0;
/****************************************************************************
* Public Functions
****************************************************************************/
void mpfs_jump_to_app(void) naked_function;
void mpfs_jump_to_app(void)
{
__asm__ __volatile__
(
"csrr a0, mhartid\n" /* Hart ID */
#ifdef CONFIG_MPFS_OPENSBI
"ld t0, g_hart_use_sbi\n" /* Load sbi usage bitmask */
"srl t0, t0, a0\n" /* Shift right by this hart */
"andi t0, t0, 1\n" /* Check the 0 bit */
"bgtz t0, mpfs_opensbi_prepare_hart\n" /* If bit was 1, jump to sbi */
#endif
"slli t1, a0, 3\n" /* To entrypoint offset */
"la t0, g_app_entrypoints\n" /* Entrypoint table base */
"add t0, t0, t1\n" /* Index in table */
"ld t0, 0(t0)\n" /* Load the address from table */
"jr t0\n" /* Jump to entrypoint */
);
}
/****************************************************************************
* Name: mpfs_set_entrypt
*
@ -168,4 +152,37 @@ uintptr_t mpfs_get_entrypt(uint64_t hartid)
return 0;
}
/****************************************************************************
* Name: mpfs_set_use_sbi
*
* Description:
* Set booting via SBI.
*
* Input Parameters:
* use_sbi - set to true if sbi is needed, false otherwise
*
* Returned value:
* OK on success, ERROR on failure
*
****************************************************************************/
int mpfs_set_use_sbi(uint64_t hartid, bool use_sbi)
{
if (hartid < ENTRYPT_CNT)
{
if (use_sbi)
{
g_hart_use_sbi |= (1 << hartid);
}
else
{
g_hart_use_sbi &= ~(1 << hartid);
}
return OK;
}
return ERROR;
}
#endif /* CONFIG_MPFS_BOOTLOADER */

View File

@ -0,0 +1,93 @@
/****************************************************************************
* arch/risc-v/src/mpfs/mpfs_entrypoints.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_MPFS_MPFS_ENTRYPOINTS_H
#define __ARCH_RISCV_SRC_MPFS_MPFS_ENTRYPOINTS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#include <stdbool.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
/****************************************************************************
* Name: mpfs_get_entrypt
*
* Description:
* Obtain Hart entrypoint
*
* Input Parameters:
* hartid - Hart ID to read
*
* Returned value:
* Entrypoint on success; 0 on failure
*
****************************************************************************/
uintptr_t mpfs_get_entrypt(uint64_t hartid);
/****************************************************************************
* Name: mpfs_set_entrypt
*
* Description:
* Modify Hart entrypoint
*
* Input Parameters:
* hartid - Hart ID to modify
* entry - Entrypoint to set
*
* Returned value:
* OK on success, ERROR on failure
*
****************************************************************************/
int mpfs_set_entrypt(uint64_t hartid, uintptr_t entry);
/****************************************************************************
* Name: mpfs_set_use_sbi
*
* Description:
* Set booting via SBI.
*
* Input Parameters:
* use_sbi - set to true if sbi is needed, false otherwise
*
* Returned value:
* OK on success, ERROR on failure
*
****************************************************************************/
int mpfs_set_use_sbi(uint64_t hartid, bool use_sbi);
#if defined(__cplusplus)
}
#endif
#endif /* __ARCH_RISCV_SRC_MPFS_MPFS_ENTRYPOINTS_H */

View File

@ -161,17 +161,8 @@ __start:
csrw mie, zero
csrw mip, zero
/* 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
/* Jump to application */
j mpfs_jump_to_app
.continue_boot: