diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h index 7b66a5e05..bcf9fc9d6 100644 --- a/include/lib/transfer_list.h +++ b/include/lib/transfer_list.h @@ -56,6 +56,7 @@ enum transfer_list_tag_id { TL_TAG_HOB_BLOCK = 2, TL_TAG_HOB_LIST = 3, TL_TAG_ACPI_TABLE_AGGREGATE = 4, + TL_TAG_TPM_EVLOG = 5, TL_TAG_OPTEE_PAGABLE_PART = 0x100, TL_TAG_DT_SPMC_MANIFEST = 0x101, TL_TAG_EXEC_EP_INFO64 = 0x102, diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 118b537e2..b43f131bc 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -299,6 +299,16 @@ int bl2_plat_handle_post_image_load(unsigned int image_id); #if (MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT) void bl2_plat_mboot_init(void); void bl2_plat_mboot_finish(void); +#if TRANSFER_LIST +int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base); +#else +static inline int +plat_handoff_mboot(__unused const void *data, __unused uint32_t data_size, + __unused void *tl_base) +{ + return -1; +} +#endif #else static inline void bl2_plat_mboot_init(void) { diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index a603f2b10..dbb6f81f7 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -129,3 +130,13 @@ void __init setup_page_tables(const mmap_region_t *bl_regions, /* Create the page tables to reflect the above mappings */ init_xlat_tables(); } + +#if ((MEASURED_BOOT || DICE_PROTECTION_ENVIRONMENT) && TRANSFER_LIST) +int plat_handoff_mboot(const void *data, uint32_t data_size, void *tl_base) +{ + if (!transfer_list_add(tl_base, TL_TAG_TPM_EVLOG, data_size, data)) + return -1; + + return 0; +} +#endif diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c index e502e7b9d..81ce1023a 100644 --- a/plat/qemu/common/qemu_bl31_setup.c +++ b/plat/qemu/common/qemu_bl31_setup.c @@ -68,6 +68,9 @@ static struct transfer_list_header *bl31_tl; void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + bool is64 = false; + uint64_t hval; + /* Initialize the console to provide early debug support */ qemu_console_init(); @@ -92,6 +95,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, * They are stored in Secure RAM, in BL2's address space. */ while (bl_params) { +#ifdef __aarch64__ + if (bl_params->image_id == BL31_IMAGE_ID && + GET_RW(bl_params->ep_info->spsr) == MODE_RW_64) + is64 = true; +#endif if (bl_params->image_id == BL32_IMAGE_ID) bl32_image_ep_info = *bl_params->ep_info; @@ -113,11 +121,19 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); #endif - if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE | - REGISTER_CONVENTION_VERSION_MASK) && - transfer_list_check_header((void *)arg3) != TL_OPS_NON) { - bl31_tl = (void *)arg3; /* saved TL address from BL2 */ - } + if (!TRANSFER_LIST || + !transfer_list_check_header((void *)arg3)) + return; + + if (is64) + hval = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION); + else + hval = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION); + + if (arg1 != hval) + return; + + bl31_tl = (void *)arg3; /* saved TL address from BL2 */ } #if ENABLE_RME @@ -309,10 +325,12 @@ void bl31_plat_runtime_setup(void) #if TRANSFER_LIST if (bl31_tl) { /* - * update the TL from S to NS memory before jump to BL33 + * Relocate the TL from S to NS memory before EL3 exit * to reflect all changes in TL done by BL32 */ - memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size); + if (!transfer_list_relocate(bl31_tl, (void *)FW_NS_HANDOFF_BASE, + bl31_tl->max_size)) + ERROR("Relocate TL to NS memory failed\n"); } #endif diff --git a/plat/qemu/qemu/qemu_measured_boot.c b/plat/qemu/qemu/qemu_measured_boot.c index 76a4da17e..54a4156c2 100644 --- a/plat/qemu/qemu/qemu_measured_boot.c +++ b/plat/qemu/qemu/qemu_measured_boot.c @@ -65,6 +65,14 @@ void bl2_plat_mboot_finish(void) event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); + dump_event_log((uint8_t *)event_log_base, event_log_cur_size); + +#if TRANSFER_LIST + if (!plat_handoff_mboot((void *)event_log_base, event_log_cur_size, + (void *)(uintptr_t)FW_HANDOFF_BASE)) + return; +#endif + rc = qemu_set_nt_fw_info( #ifdef SPD_opteed (uintptr_t)event_log_base, @@ -101,7 +109,6 @@ void bl2_plat_mboot_finish(void) } #endif /* defined(SPD_tspd) || defined(SPD_spmd) */ - dump_event_log((uint8_t *)event_log_base, event_log_cur_size); } int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data) diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c index 9e8384844..8910ec60a 100644 --- a/services/spd/opteed/opteed_main.c +++ b/services/spd/opteed/opteed_main.c @@ -190,24 +190,28 @@ static int32_t opteed_setup(void) if (!optee_ep_info->pc) return 1; - if (TRANSFER_LIST && - optee_ep_info->args.arg1 == (TRANSFER_LIST_SIGNATURE | - REGISTER_CONVENTION_VERSION_MASK)) { - tl = (void *)optee_ep_info->args.arg3; - if (transfer_list_check_header(tl) == TL_OPS_NON) { - return 1; - } - - opteed_rw = GET_RW(optee_ep_info->spsr); + tl = (void *)optee_ep_info->args.arg3; + if (TRANSFER_LIST && transfer_list_check_header(tl)) { te = transfer_list_find(tl, TL_TAG_FDT); dt = transfer_list_entry_data(te); + opteed_rw = GET_RW(optee_ep_info->spsr); if (opteed_rw == OPTEE_AARCH64) { + if (optee_ep_info->args.arg1 != + TRANSFER_LIST_HANDOFF_X1_VALUE( + REGISTER_CONVENTION_VERSION)) + return 1; + arg0 = (uint64_t)dt; arg2 = 0; } else { - arg2 = (uint64_t)dt; + if (optee_ep_info->args.arg1 != + TRANSFER_LIST_HANDOFF_R1_VALUE( + REGISTER_CONVENTION_VERSION)) + return 1; + arg0 = 0; + arg2 = (uint64_t)dt; } arg1 = optee_ep_info->args.arg1;