Skip to content

Commit

Permalink
Allow custom boot flow for PolarFire boards
Browse files Browse the repository at this point in the history
To use prominent open-source bootloaders (such as U-Boot SPL, Coreboot,
and EDK2) on PolarFire boards, we need a mechanism to boot all HARTs
(both E51 and U54s) at same entry point in M-mode.

This patch extends HSS boot flow to support booting all HARTs (both E51
and U54s) in M-mode at commong entry point. We call this mechanism as
custom boot flow and it is enabled via kconfig option. The first image
in HSS payload will be loaded by default and the entry point of the
first image owner HART will be used as common entry point.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
  • Loading branch information
avpatel committed Oct 8, 2020
1 parent 76b34dd commit 2cd45c9
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 0 deletions.
103 changes: 103 additions & 0 deletions boards/icicle-kit-es/def_config_custom
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)

#
# Services
#
CONFIG_SERVICE_BOOT=y

#
# Boot Service
#
CONFIG_SERVICE_BOOT_SETS_SUPPORT=y
CONFIG_SERVICE_BOOT_DDR_TARGET_ADDR=0xB0000000
# CONFIG_SERVICE_BOOT_USE_PAYLOAD is not set
CONFIG_SERVICE_BOOT_CUSTOM_FLOW=y
CONFIG_SERVICE_BOOT_MMC_USE_GPT=y
CONFIG_SERVICE_DDR=y
CONFIG_SERVICE_GOTO=y
# CONFIG_SERVICE_CRYPTO is not set
# CONFIG_SERVICE_FLASHFREEZE is not set
# CONFIG_SERVICE_POWERMODE is not set
CONFIG_SERVICE_MMC=y

#
# MMC Mode
#
CONFIG_SERVICE_MMC_MODE_EMMC=y
# CONFIG_SERVICE_MMC_MODE_SDCARD is not set

#
# MMC Voltage
#
# CONFIG_SERVICE_MMC_BUS_VOLTAGE_1V8 is not set
CONFIG_SERVICE_MMC_BUS_VOLTAGE_3V3=y
# CONFIG_SERVICE_QSPI is not set
CONFIG_SERVICE_SGDMA=y
# CONFIG_SERVICE_SPI is not set
# CONFIG_SERVICE_UART is not set
# CONFIG_SERVICE_WDOG is not set
CONFIG_SERVICE_IPI_POLL=y
CONFIG_SERVICE_OPENSBI=y
# CONFIG_SERVICE_YMODEM is not set
CONFIG_SERVICE_USBDMSC=y

#
# USB Device Mass Storage Class
#
CONFIG_SERVICE_USBDMSC_REGISTER=y
CONFIG_SERVICE_TINYCLI=y

#
# Tiny Command Line Interface
#
CONFIG_SERVICE_TINYCLI_TIMEOUT=5
# CONFIG_SERVICE_TINYCLI_REGISTER is not set

#
# Compression
#
# CONFIG_COMPRESSION is not set

#
# General Configuration Options
#
CONFIG_OPENSBI=y

#
# OpenSBI
#
# CONFIG_PROVIDE_DTB is not set
# CONFIG_SUPERLOOP_IN_U_MODE is not set

#
# Memory Options
#
CONFIG_MEMTEST=y
CONFIG_IPI_MAX_NUM_QUEUE_MESSAGES=16
# CONFIG_IPI_FIXED_BASE is not set
CONFIG_USE_PDMA=y
# CONFIG_INITIALIZE_MEMORIES is not set

#
# Build Options
#
CONFIG_COLOR_OUTPUT=y
CONFIG_USE_LOGO=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
# CONFIG_CC_DUMP_STACKSIZE is not set
# CONFIG_LD_RELAX is not set
CONFIG_CC_USE_MAKEDEP=y
CONFIG_CC_USE_GNU_BUILD_ID=y
CONFIG_CC_HAS_INTTYPES=y
CONFIG_DISPLAY_TOOL_VERSIONS=y

#
# Debug Options
#
CONFIG_DEBUG_LOG_STATE_TRANSITIONS=y
# CONFIG_DEBUG_LOOP_TIMES is not set
CONFIG_DEBUG_LOOP_TIMES_THRESHOLD=2500000
# CONFIG_DEBUG_IPI_STATS is not set
# CONFIG_DEBUG_CHUNK_DOWNLOADS is not set
# CONFIG_DEBUG_MSCGEN_IPI is not set
# CONFIG_DEBUG_PROFILING_SUPPORT is not set
103 changes: 103 additions & 0 deletions boards/icicle-kit-es/def_config_custom.sdcard
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib)

#
# Services
#
CONFIG_SERVICE_BOOT=y

#
# Boot Service
#
CONFIG_SERVICE_BOOT_SETS_SUPPORT=y
CONFIG_SERVICE_BOOT_DDR_TARGET_ADDR=0xB0000000
# CONFIG_SERVICE_BOOT_USE_PAYLOAD is not set
CONFIG_SERVICE_BOOT_CUSTOM_FLOW=y
CONFIG_SERVICE_BOOT_MMC_USE_GPT=y
CONFIG_SERVICE_DDR=y
CONFIG_SERVICE_GOTO=y
# CONFIG_SERVICE_CRYPTO is not set
# CONFIG_SERVICE_FLASHFREEZE is not set
# CONFIG_SERVICE_POWERMODE is not set
CONFIG_SERVICE_MMC=y

#
# MMC Mode
#
# CONFIG_SERVICE_MMC_MODE_EMMC is not set
CONFIG_SERVICE_MMC_MODE_SDCARD=y

#
# MMC Voltage
#
# CONFIG_SERVICE_MMC_BUS_VOLTAGE_1V8 is not set
CONFIG_SERVICE_MMC_BUS_VOLTAGE_3V3=y
# CONFIG_SERVICE_QSPI is not set
CONFIG_SERVICE_SGDMA=y
# CONFIG_SERVICE_SPI is not set
# CONFIG_SERVICE_UART is not set
# CONFIG_SERVICE_WDOG is not set
CONFIG_SERVICE_IPI_POLL=y
CONFIG_SERVICE_OPENSBI=y
# CONFIG_SERVICE_YMODEM is not set
CONFIG_SERVICE_USBDMSC=y

#
# USB Device Mass Storage Class
#
CONFIG_SERVICE_USBDMSC_REGISTER=y
CONFIG_SERVICE_TINYCLI=y

#
# Tiny Command Line Interface
#
CONFIG_SERVICE_TINYCLI_TIMEOUT=5
# CONFIG_SERVICE_TINYCLI_REGISTER is not set

#
# Compression
#
# CONFIG_COMPRESSION is not set

#
# General Configuration Options
#
CONFIG_OPENSBI=y

#
# OpenSBI
#
# CONFIG_PROVIDE_DTB is not set
# CONFIG_SUPERLOOP_IN_U_MODE is not set

#
# Memory Options
#
CONFIG_MEMTEST=y
CONFIG_IPI_MAX_NUM_QUEUE_MESSAGES=16
# CONFIG_IPI_FIXED_BASE is not set
CONFIG_USE_PDMA=y
# CONFIG_INITIALIZE_MEMORIES is not set

#
# Build Options
#
CONFIG_COLOR_OUTPUT=y
CONFIG_USE_LOGO=y
CONFIG_CC_STACKPROTECTOR_STRONG=y
# CONFIG_CC_DUMP_STACKSIZE is not set
# CONFIG_LD_RELAX is not set
CONFIG_CC_USE_MAKEDEP=y
CONFIG_CC_USE_GNU_BUILD_ID=y
CONFIG_CC_HAS_INTTYPES=y
CONFIG_DISPLAY_TOOL_VERSIONS=y

#
# Debug Options
#
CONFIG_DEBUG_LOG_STATE_TRANSITIONS=y
# CONFIG_DEBUG_LOOP_TIMES is not set
CONFIG_DEBUG_LOOP_TIMES_THRESHOLD=2500000
# CONFIG_DEBUG_IPI_STATS is not set
# CONFIG_DEBUG_CHUNK_DOWNLOADS is not set
# CONFIG_DEBUG_MSCGEN_IPI is not set
# CONFIG_DEBUG_PROFILING_SUPPORT is not set
4 changes: 4 additions & 0 deletions init/hss_boot_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,15 @@ bool HSS_BootInit(void)
HSS_Register_Boot_Image(pBootImage);
mHSS_DEBUG_PRINTF(LOG_NORMAL, "Boot Image registered..." CRLF);

# if defined(CONFIG_SERVICE_BOOT_CUSTOM_FLOW)
result = HSS_Boot_Custom();
# else
if (HSS_Boot_RestartCore(HSS_HART_ALL) == IPI_SUCCESS) {
result = true;
} else {
result = false;
}
# endif
} else {
mHSS_DEBUG_PRINTF(LOG_ERROR, "%s boot image failed CRC" CRLF,
decompressedFlag ? "decompressed":"");
Expand Down
8 changes: 8 additions & 0 deletions services/boot/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ config SERVICE_BOOT_USE_PAYLOAD
help
This feature enables booting a directly contained payload.

config SERVICE_BOOT_CUSTOM_FLOW
bool "Use Custom Boot Flow"
default n
depends on SERVICE_BOOT
help
This feature enables custom booting flow where all HARTs
will jump to same entry point in M-mode.

config SERVICE_BOOT_DDR_TARGET_ADDR
hex "Target Base address for BOOT to DDR copy"
default 0xB0000000
Expand Down
94 changes: 94 additions & 0 deletions services/boot/hss_boot_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,100 @@ void HSS_Register_Boot_Image(struct HSS_BootImage *pImage)
pBootImage = pImage;
}

static uintptr_t Custom_entryPoint;
static uint8_t Custom_privMode = PRV_M;

bool HSS_Boot_Custom(void)
{
int i;
size_t numChunks = 0;
size_t firstChunk = 0;
size_t chunkNum;
size_t subChunkOffset;
enum HSSHartId target = 0;
struct HSS_BootChunkDesc const *pChunk;
struct HSS_BootZIChunkDesc const *pZiChunk;

if (!pBootImage)
return false;

for (i = 0; i < (MAX_NUM_HARTS-1); i++) {
if (pBootImage->hart[i].numChunks) {
target = i + 1;
numChunks = pBootImage->hart[i].numChunks;
firstChunk = pBootImage->hart[i].firstChunk;
}
}

if (!numChunks || !target) {
mHSS_DEBUG_PRINTF(LOG_ERROR, "Failed to find target HART" CRLF);
return false;
}

mHSS_DEBUG_PRINTF(LOG_NORMAL, "Zeroing chunks for HART%d" CRLF, target);
pZiChunk = (struct HSS_BootZIChunkDesc const *)((char *)pBootImage + pBootImage->ziChunkTableOffset);
chunkNum = 0u;
while (pZiChunk->size != 0u) {
if (target == pZiChunk->owner) {
#ifdef CONFIG_DEBUG_CHUNK_DOWNLOADS
mHSS_DEBUG_PRINTF(LOG_NORMAL, "%d:ziChunk->0x%X, %u bytes" CRLF,
chunkNum, (uint64_t)pZiChunk->execAddr, pZiChunk->size);
#endif
boot_do_zero_init_chunk(pZiChunk);
chunkNum++;
}
pZiChunk++;
}

pChunk = (struct HSS_BootChunkDesc *)((char *)pBootImage + pBootImage->chunkTableOffset);
chunkNum = 0u;
subChunkOffset = 0u;
pChunk += firstChunk;
mHSS_DEBUG_PRINTF(LOG_NORMAL, "Downloading chunks for HART%d at 0x%X" CRLF, target, (uint64_t)pChunk->execAddr);
while (pChunk->size != 0u) {
if ((pChunk->owner == target) && (HSS_PMP_CheckWrite(target, pChunk->execAddr, pChunk->size))) {
#ifdef CONFIG_DEBUG_CHUNK_DOWNLOADS
if (!subChunkOffset) {
mHSS_DEBUG_PRINTF(LOG_NORMAL, "%d:chunk@0x%X->0x%X, %u bytes" CRLF,
chunkNum, (uint64_t)pChunk->loadAddr,
(uint64_t)pChunk->execAddr, pChunk->size);
}
#endif
// check each hart to see if it wants to transmit
#define SUB_CHUNK_SIZE 256u
#ifdef SUB_CHUNK_SIZE
boot_do_download_chunk(pChunk, subChunkOffset, SUB_CHUNK_SIZE);

subChunkOffset += SUB_CHUNK_SIZE;
if (subChunkOffset > pChunk->size) {
subChunkOffset = 0u;
chunkNum++;
pChunk++;
}
#else
boot_do_download_chunk(pChunk, 0u, pChunk->size);
chunkNum++;
pChunk++;
#endif
} else {
pChunk++;
}
}

// For custom boot-flow, all U54 HARTs and E51 HART
// should jump to commong entry point in M-mode
Custom_entryPoint = pBootImage->hart[target - 1].entryPoint;
mHSS_DEBUG_PRINTF(LOG_NORMAL, "All HARTs jumping to entry address 0x%lx in M-mode" CRLF, Custom_entryPoint);
for (i = 0; i < (MAX_NUM_HARTS-1); i++) {
IPI_Send(i + 1, IPI_MSG_OPENSBI_INIT, 0,
Custom_privMode, &Custom_entryPoint);
}

((void (*)(uintptr_t, uintptr_t))Custom_entryPoint)(current_hartid(), 0);

return true;
}

/*!
* \brief PMP Setup Handler
*
Expand Down
2 changes: 2 additions & 0 deletions services/boot/hss_boot_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ void HSS_Register_Boot_Image(struct HSS_BootImage *pImage);

bool HSS_Boot_Harts(enum HSSHartId const source);

bool HSS_Boot_Custom(void);

extern struct StateMachine boot_service1;
extern struct StateMachine boot_service2;
extern struct StateMachine boot_service3;
Expand Down

0 comments on commit 2cd45c9

Please sign in to comment.