mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 09:34:18 +00:00
feat(qemu): implement firmware handoff on qemu
Implement firmware handoff from BL2 to BL33 on qemu platform compliant to Firmware handoff specification v0.9. Change-Id: Id8d5206a71ef6ec97cf3c97995de328ebf0600cc Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
This commit is contained in:
parent
3ba2c15147
commit
322af23445
6 changed files with 123 additions and 9 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -18,6 +18,9 @@
|
|||
#include <common/fdt_fixup.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <lib/optee_utils.h>
|
||||
#if TRANSFER_LIST
|
||||
#include <lib/transfer_list.h>
|
||||
#endif
|
||||
#include <lib/utils.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
|
@ -48,6 +51,9 @@
|
|||
|
||||
/* Data structure which holds the extents of the trusted SRAM for BL2 */
|
||||
static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
|
||||
#if TRANSFER_LIST
|
||||
static struct transfer_list_header *bl2_tl;
|
||||
#endif
|
||||
|
||||
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
|
||||
u_register_t arg2, u_register_t arg3)
|
||||
|
@ -73,6 +79,9 @@ static void security_setup(void)
|
|||
|
||||
static void update_dt(void)
|
||||
{
|
||||
#if TRANSFER_LIST
|
||||
struct transfer_list_entry *te;
|
||||
#endif
|
||||
int ret;
|
||||
void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
|
||||
|
||||
|
@ -95,16 +104,40 @@ static void update_dt(void)
|
|||
ret = fdt_pack(fdt);
|
||||
if (ret < 0)
|
||||
ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
|
||||
|
||||
#if TRANSFER_LIST
|
||||
// create a TE
|
||||
te = transfer_list_add(bl2_tl, TL_TAG_FDT, fdt_totalsize(fdt), fdt);
|
||||
if (!te) {
|
||||
ERROR("Failed to add FDT entry to Transfer List\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void bl2_platform_setup(void)
|
||||
{
|
||||
#if TRANSFER_LIST
|
||||
bl2_tl = transfer_list_init((void *)(uintptr_t)FW_HANDOFF_BASE,
|
||||
FW_HANDOFF_SIZE);
|
||||
if (!bl2_tl) {
|
||||
ERROR("Failed to initialize Transfer List at 0x%lx\n",
|
||||
(unsigned long)FW_HANDOFF_BASE);
|
||||
}
|
||||
#endif
|
||||
security_setup();
|
||||
update_dt();
|
||||
|
||||
/* TODO Initialize timer */
|
||||
}
|
||||
|
||||
void qemu_bl2_sync_transfer_list(void)
|
||||
{
|
||||
#if TRANSFER_LIST
|
||||
transfer_list_update_checksum(bl2_tl);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bl2_plat_arch_setup(void)
|
||||
{
|
||||
const mmap_region_t bl_regions[] = {
|
||||
|
@ -221,6 +254,10 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
|
|||
#if defined(SPD_spmd)
|
||||
bl_mem_params_node_t *bl32_mem_params = NULL;
|
||||
#endif
|
||||
#if TRANSFER_LIST
|
||||
struct transfer_list_header *ns_tl = NULL;
|
||||
struct transfer_list_entry *te = NULL;
|
||||
#endif
|
||||
|
||||
assert(bl_mem_params);
|
||||
|
||||
|
@ -275,6 +312,8 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
|
|||
pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
|
||||
#endif
|
||||
|
||||
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
|
||||
|
||||
#if ARM_LINUX_KERNEL_AS_BL33
|
||||
/*
|
||||
* According to the file ``Documentation/arm64/booting.txt`` of
|
||||
|
@ -287,12 +326,49 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id)
|
|||
bl_mem_params->ep_info.args.arg1 = 0U;
|
||||
bl_mem_params->ep_info.args.arg2 = 0U;
|
||||
bl_mem_params->ep_info.args.arg3 = 0U;
|
||||
#elif TRANSFER_LIST
|
||||
if (bl2_tl) {
|
||||
// relocate the tl to pre-allocate NS memory
|
||||
ns_tl = transfer_list_relocate(bl2_tl,
|
||||
(void *)(uintptr_t)FW_NS_HANDOFF_BASE,
|
||||
bl2_tl->max_size);
|
||||
if (!ns_tl) {
|
||||
ERROR("Relocate TL to 0x%lx failed\n",
|
||||
(unsigned long)FW_NS_HANDOFF_BASE);
|
||||
return -1;
|
||||
}
|
||||
NOTICE("Transfer list handoff to BL33\n");
|
||||
transfer_list_dump(ns_tl);
|
||||
|
||||
te = transfer_list_find(ns_tl, TL_TAG_FDT);
|
||||
|
||||
bl_mem_params->ep_info.args.arg1 =
|
||||
TRANSFER_LIST_SIGNATURE |
|
||||
REGISTER_CONVENTION_VERSION_MASK;
|
||||
bl_mem_params->ep_info.args.arg3 = (uintptr_t)ns_tl;
|
||||
|
||||
if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_32) {
|
||||
// aarch32
|
||||
bl_mem_params->ep_info.args.arg0 = 0;
|
||||
bl_mem_params->ep_info.args.arg2 = te ?
|
||||
(uintptr_t)transfer_list_entry_data(te)
|
||||
: 0;
|
||||
} else {
|
||||
// aarch64
|
||||
bl_mem_params->ep_info.args.arg0 = te ?
|
||||
(uintptr_t)transfer_list_entry_data(te)
|
||||
: 0;
|
||||
bl_mem_params->ep_info.args.arg2 = 0;
|
||||
}
|
||||
} else {
|
||||
// Legacy handoff
|
||||
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
|
||||
}
|
||||
#else
|
||||
/* BL33 expects to receive the primary CPU MPID (through r0) */
|
||||
bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
|
||||
#endif
|
||||
#endif // ARM_LINUX_KERNEL_AS_BL33
|
||||
|
||||
bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry();
|
||||
break;
|
||||
#ifdef SPD_spmd
|
||||
#if SPMD_SPM_AT_SEL2
|
||||
|
|
|
@ -47,6 +47,14 @@
|
|||
#define MAP_FLASH1 MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
|
||||
MT_MEMORY | MT_RO | MT_SECURE)
|
||||
|
||||
#ifdef FW_HANDOFF_BASE
|
||||
#define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_SECURE)
|
||||
#endif
|
||||
#ifdef FW_NS_HANDOFF_BASE
|
||||
#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
#endif
|
||||
/*
|
||||
* Table of regions for various BL stages to map using the MMU.
|
||||
* This doesn't include TZRAM as the 'mem_layout' argument passed to
|
||||
|
@ -84,6 +92,9 @@ static const mmap_region_t plat_qemu_mmap[] = {
|
|||
QEMU_SP_IMAGE_MMAP,
|
||||
#else
|
||||
MAP_BL32_MEM,
|
||||
#endif
|
||||
#ifdef MAP_FW_HANDOFF
|
||||
MAP_FW_HANDOFF,
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
@ -98,6 +109,12 @@ static const mmap_region_t plat_qemu_mmap[] = {
|
|||
#ifdef MAP_DEVICE2
|
||||
MAP_DEVICE2,
|
||||
#endif
|
||||
#ifdef MAP_FW_HANDOFF
|
||||
MAP_FW_HANDOFF,
|
||||
#endif
|
||||
#ifdef MAP_FW_NS_HANDOFF
|
||||
MAP_FW_NS_HANDOFF,
|
||||
#endif
|
||||
#if SPM_MM
|
||||
MAP_NS_DRAM0,
|
||||
QEMU_SPM_BUF_EL3_MMAP,
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <common/desc_image_load.h>
|
||||
|
||||
#include "qemu_private.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* This function is a wrapper of a common function which flushes the data
|
||||
* structures so that they are visible in memory for the next BL image.
|
||||
|
@ -13,6 +15,7 @@
|
|||
void plat_flush_next_bl_params(void)
|
||||
{
|
||||
flush_bl_params_desc();
|
||||
qemu_bl2_sync_transfer_list();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -40,4 +40,6 @@ int qemu_set_nt_fw_info(
|
|||
size_t log_size,
|
||||
uintptr_t *ns_log_addr);
|
||||
|
||||
void qemu_bl2_sync_transfer_list(void);
|
||||
|
||||
#endif /* QEMU_PRIVATE_H */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -151,9 +151,17 @@
|
|||
* current BL3-1 debug size plus a little space for growth.
|
||||
*/
|
||||
#define BL31_BASE (BL31_LIMIT - 0x60000)
|
||||
#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE)
|
||||
#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE - FW_HANDOFF_SIZE)
|
||||
#define BL31_PROGBITS_LIMIT BL1_RW_BASE
|
||||
|
||||
#if TRANSFER_LIST
|
||||
#define FW_HANDOFF_BASE BL31_LIMIT
|
||||
#define FW_HANDOFF_LIMIT (FW_HANDOFF_BASE + FW_HANDOFF_SIZE)
|
||||
#define FW_HANDOFF_SIZE 0x4000
|
||||
#else
|
||||
#define FW_HANDOFF_SIZE 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* BL3-2 specific defines.
|
||||
|
@ -172,16 +180,20 @@
|
|||
# define BL32_MEM_BASE BL_RAM_BASE
|
||||
# define BL32_MEM_SIZE BL_RAM_SIZE
|
||||
# define BL32_BASE BL32_SRAM_BASE
|
||||
# define BL32_LIMIT BL32_SRAM_LIMIT
|
||||
# define BL32_LIMIT (BL32_SRAM_LIMIT - FW_HANDOFF_SIZE)
|
||||
#elif BL32_RAM_LOCATION_ID == SEC_DRAM_ID
|
||||
# define BL32_MEM_BASE SEC_DRAM_BASE
|
||||
# define BL32_MEM_SIZE SEC_DRAM_SIZE
|
||||
# define BL32_BASE BL32_DRAM_BASE
|
||||
# define BL32_LIMIT BL32_DRAM_LIMIT
|
||||
# define BL32_LIMIT (BL32_DRAM_LIMIT - FW_HANDOFF_SIZE)
|
||||
#else
|
||||
# error "Unsupported BL32_RAM_LOCATION_ID value"
|
||||
#endif
|
||||
|
||||
#if TRANSFER_LIST
|
||||
#define FW_NS_HANDOFF_BASE (NS_IMAGE_OFFSET - FW_HANDOFF_SIZE)
|
||||
#endif
|
||||
|
||||
#define NS_IMAGE_OFFSET (NS_DRAM0_BASE + 0x20000000)
|
||||
#define NS_IMAGE_MAX_SIZE (NS_DRAM0_SIZE - 0x20000000)
|
||||
|
||||
|
|
|
@ -39,6 +39,10 @@ $(eval $(call add_define,SPMC_OPTEE))
|
|||
add-lib-optee := yes
|
||||
endif
|
||||
|
||||
ifeq (${TRANSFER_LIST},1)
|
||||
include lib/transfer_list/transfer_list.mk
|
||||
endif
|
||||
|
||||
ifeq ($(NEED_BL32),yes)
|
||||
$(eval $(call add_define,QEMU_LOAD_BL32))
|
||||
endif
|
||||
|
|
Loading…
Add table
Reference in a new issue