mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 14:55:16 +00:00
feat(plat/st): add STM32MP_EMMC_BOOT option
Added a new STM32MP_EMMC_BOOT option, which is used to look for SSBL in the same eMMC boot partition TF-A booted from at a fixed 256k offset. In case STM32 image header is not found, the boot process rolls back to a GPT partition look-up scheme. Signed-off-by: Vyacheslav Yurkov <uvv.mail@gmail.com> Change-Id: I85a87dc9ae7f2b915ed8e584be80f4b3588efc48
This commit is contained in:
parent
f3d2750aa2
commit
214c8a8d08
3 changed files with 92 additions and 5 deletions
|
@ -62,6 +62,30 @@ static const io_block_dev_spec_t mmc_block_dev_spec = {
|
||||||
.block_size = MMC_BLOCK_SIZE,
|
.block_size = MMC_BLOCK_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if STM32MP_EMMC_BOOT
|
||||||
|
static io_block_spec_t emmc_boot_ssbl_block_spec = {
|
||||||
|
.offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
|
||||||
|
.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
|
||||||
|
/* It's used as temp buffer in block driver */
|
||||||
|
.buffer = {
|
||||||
|
.offset = (size_t)&block_buffer,
|
||||||
|
.length = MMC_BLOCK_SIZE,
|
||||||
|
},
|
||||||
|
.ops = {
|
||||||
|
.read = mmc_boot_part_read_blocks,
|
||||||
|
.write = NULL,
|
||||||
|
},
|
||||||
|
.block_size = MMC_BLOCK_SIZE,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct io_mmc_dev_spec mmc_device_spec = {
|
||||||
|
.use_boot_part = false,
|
||||||
|
};
|
||||||
|
|
||||||
static const io_dev_connector_t *mmc_dev_con;
|
static const io_dev_connector_t *mmc_dev_con;
|
||||||
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
|
#endif /* STM32MP_SDMMC || STM32MP_EMMC */
|
||||||
|
|
||||||
|
@ -236,6 +260,38 @@ static int open_storage(const uintptr_t spec)
|
||||||
return io_dev_init(storage_dev_handle, 0);
|
return io_dev_init(storage_dev_handle, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STM32MP_EMMC_BOOT
|
||||||
|
static uint32_t get_boot_part_ssbl_header(void)
|
||||||
|
{
|
||||||
|
uint32_t magic = 0;
|
||||||
|
int io_result;
|
||||||
|
size_t bytes_read;
|
||||||
|
|
||||||
|
io_result = register_io_dev_block(&mmc_dev_con);
|
||||||
|
if (io_result != 0) {
|
||||||
|
panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
|
||||||
|
&storage_dev_handle);
|
||||||
|
assert(io_result == 0);
|
||||||
|
|
||||||
|
io_result = io_open(storage_dev_handle, (uintptr_t) &emmc_boot_ssbl_block_spec,
|
||||||
|
&image_dev_handle);
|
||||||
|
assert(io_result == 0);
|
||||||
|
|
||||||
|
io_result = io_read(image_dev_handle, (uintptr_t) &magic, sizeof(magic),
|
||||||
|
&bytes_read);
|
||||||
|
assert(io_result == 0);
|
||||||
|
assert(bytes_read == sizeof(magic));
|
||||||
|
|
||||||
|
io_result = io_dev_close(storage_dev_handle);
|
||||||
|
assert(io_result == 0);
|
||||||
|
|
||||||
|
return magic;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void print_boot_device(boot_api_context_t *boot_context)
|
static void print_boot_device(boot_api_context_t *boot_context)
|
||||||
{
|
{
|
||||||
switch (boot_context->boot_interface_selected) {
|
switch (boot_context->boot_interface_selected) {
|
||||||
|
@ -273,7 +329,8 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
|
||||||
uint8_t idx;
|
uint8_t idx;
|
||||||
struct stm32image_part_info *part;
|
struct stm32image_part_info *part;
|
||||||
struct stm32_sdmmc2_params params;
|
struct stm32_sdmmc2_params params;
|
||||||
const partition_entry_t *entry;
|
const partition_entry_t *entry __unused;
|
||||||
|
uint32_t magic __unused;
|
||||||
|
|
||||||
zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
|
zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
|
||||||
|
|
||||||
|
@ -305,6 +362,26 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stm32image_dev_info_spec.device_size =
|
||||||
|
stm32_sdmmc2_mmc_get_device_size();
|
||||||
|
|
||||||
|
#if STM32MP_EMMC_BOOT
|
||||||
|
magic = get_boot_part_ssbl_header();
|
||||||
|
|
||||||
|
if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
|
||||||
|
VERBOSE("%s, header found, jump to emmc load\n", __func__);
|
||||||
|
idx = IMG_IDX_BL33;
|
||||||
|
part = &stm32image_dev_info_spec.part_info[idx];
|
||||||
|
part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
|
||||||
|
part->bkp_offset = 0U;
|
||||||
|
mmc_device_spec.use_boot_part = true;
|
||||||
|
|
||||||
|
goto emmc_boot;
|
||||||
|
} else {
|
||||||
|
WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Open MMC as a block device to read GPT table */
|
/* Open MMC as a block device to read GPT table */
|
||||||
io_result = register_io_dev_block(&mmc_dev_con);
|
io_result = register_io_dev_block(&mmc_dev_con);
|
||||||
if (io_result != 0) {
|
if (io_result != 0) {
|
||||||
|
@ -320,9 +397,6 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
|
||||||
io_result = io_dev_close(storage_dev_handle);
|
io_result = io_dev_close(storage_dev_handle);
|
||||||
assert(io_result == 0);
|
assert(io_result == 0);
|
||||||
|
|
||||||
stm32image_dev_info_spec.device_size =
|
|
||||||
stm32_sdmmc2_mmc_get_device_size();
|
|
||||||
|
|
||||||
for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
|
for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
|
||||||
part = &stm32image_dev_info_spec.part_info[idx];
|
part = &stm32image_dev_info_spec.part_info[idx];
|
||||||
entry = get_partition_entry(part->name);
|
entry = get_partition_entry(part->name);
|
||||||
|
@ -335,6 +409,9 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
|
||||||
part->bkp_offset = 0U;
|
part->bkp_offset = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if STM32MP_EMMC_BOOT
|
||||||
|
emmc_boot:
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Re-open MMC with io_mmc, for better perfs compared to
|
* Re-open MMC with io_mmc, for better perfs compared to
|
||||||
* io_block.
|
* io_block.
|
||||||
|
@ -342,7 +419,8 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
|
||||||
io_result = register_io_dev_mmc(&mmc_dev_con);
|
io_result = register_io_dev_mmc(&mmc_dev_con);
|
||||||
assert(io_result == 0);
|
assert(io_result == 0);
|
||||||
|
|
||||||
io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
|
io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
|
||||||
|
&storage_dev_handle);
|
||||||
assert(io_result == 0);
|
assert(io_result == 0);
|
||||||
|
|
||||||
io_result = register_io_dev_stm32image(&stm32image_dev_con);
|
io_result = register_io_dev_stm32image(&stm32image_dev_con);
|
||||||
|
|
|
@ -88,6 +88,12 @@
|
||||||
*/
|
*/
|
||||||
#define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE
|
#define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SSBL offset in case it's stored in eMMC boot partition.
|
||||||
|
* We can fix it to 256K because TF-A size can't be bigger than SRAM
|
||||||
|
*/
|
||||||
|
#define PLAT_EMMC_BOOT_SSBL_OFFSET U(0x40000)
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* DTB specific defines.
|
* DTB specific defines.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
|
@ -42,6 +42,7 @@ STM32MP_SDMMC ?= 0
|
||||||
STM32MP_RAW_NAND ?= 0
|
STM32MP_RAW_NAND ?= 0
|
||||||
STM32MP_SPI_NAND ?= 0
|
STM32MP_SPI_NAND ?= 0
|
||||||
STM32MP_SPI_NOR ?= 0
|
STM32MP_SPI_NOR ?= 0
|
||||||
|
STM32MP_EMMC_BOOT ?= 0
|
||||||
|
|
||||||
ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \
|
ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \
|
||||||
${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
|
${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
|
||||||
|
@ -77,6 +78,7 @@ $(eval $(call assert_booleans,\
|
||||||
STM32MP_RAW_NAND \
|
STM32MP_RAW_NAND \
|
||||||
STM32MP_SPI_NAND \
|
STM32MP_SPI_NAND \
|
||||||
STM32MP_SPI_NOR \
|
STM32MP_SPI_NOR \
|
||||||
|
STM32MP_EMMC_BOOT \
|
||||||
PLAT_XLAT_TABLES_DYNAMIC \
|
PLAT_XLAT_TABLES_DYNAMIC \
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
@ -93,6 +95,7 @@ $(eval $(call add_defines,\
|
||||||
STM32MP_RAW_NAND \
|
STM32MP_RAW_NAND \
|
||||||
STM32MP_SPI_NAND \
|
STM32MP_SPI_NAND \
|
||||||
STM32MP_SPI_NOR \
|
STM32MP_SPI_NOR \
|
||||||
|
STM32MP_EMMC_BOOT \
|
||||||
PLAT_XLAT_TABLES_DYNAMIC \
|
PLAT_XLAT_TABLES_DYNAMIC \
|
||||||
STM32_TF_A_COPIES \
|
STM32_TF_A_COPIES \
|
||||||
PLAT_PARTITION_MAX_ENTRIES \
|
PLAT_PARTITION_MAX_ENTRIES \
|
||||||
|
|
Loading…
Add table
Reference in a new issue