diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 5765226cb..9618700a2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -260,6 +260,8 @@ int arm_set_nt_fw_info( uintptr_t log_addr, #endif size_t log_size, uintptr_t *ns_log_addr); +int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size); +int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size); #endif /* MEASURED_BOOT */ /* diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c index 15ea05997..8815b74e4 100644 --- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c @@ -7,6 +7,7 @@ #include #include +#include /* Event Log data */ static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; @@ -21,13 +22,23 @@ const event_log_metadata_t fvp_event_log_metadata[] = { void bl1_plat_mboot_init(void) { - event_log_init(event_log, PLAT_ARM_EVENT_LOG_MAX_SIZE, 0U); + event_log_init(event_log, event_log + sizeof(event_log)); + event_log_write_header(); } void bl1_plat_mboot_finish(void) { - /* - * ToDo: populate tb_fw_config with Event Log address, its maximum size - * and filled size - */ + size_t event_log_cur_size; + + event_log_cur_size = event_log_get_cur_size(event_log); + int rc = arm_set_tb_fw_info((uintptr_t)event_log, + event_log_cur_size); + if (rc != 0) { + /* + * It is a fatal error because on FVP platform, BL2 software + * assumes that a valid Event Log buffer exist and it will use + * same Event Log buffer to append image measurements. + */ + panic(); + } } diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c index f5d829a23..16e8d79ee 100644 --- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -10,7 +10,7 @@ #include /* Event Log data */ -static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; +static uint64_t event_log_base; /* FVP table with platform specific image IDs, names and PCRs */ const event_log_metadata_t fvp_event_log_metadata[] = { @@ -29,8 +29,33 @@ const event_log_metadata_t fvp_event_log_metadata[] = { void bl2_plat_mboot_init(void) { - event_log_init(event_log, event_log + sizeof(event_log)); - event_log_write_header(); + uint8_t *event_log_start; + uint8_t *event_log_finish; + size_t bl1_event_log_size; + int rc; + + rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size); + if (rc != 0) { + ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n", + __func__); + /* + * It is a fatal error because on FVP platform, BL2 software + * assumes that a valid Event Log buffer exist and it will use + * same Event Log buffer to append image measurements. + */ + panic(); + } + + /* + * BL1 and BL2 share the same Event Log buffer and that BL2 will + * append its measurements after BL1's + */ + event_log_start = (uint8_t *)((uintptr_t)event_log_base + + bl1_event_log_size); + event_log_finish = (uint8_t *)((uintptr_t)event_log_base + + PLAT_ARM_EVENT_LOG_MAX_SIZE); + + event_log_init((uint8_t *)event_log_start, event_log_finish); } void bl2_plat_mboot_finish(void) @@ -43,11 +68,11 @@ void bl2_plat_mboot_finish(void) /* Event Log filled size */ size_t event_log_cur_size; - event_log_cur_size = event_log_get_cur_size(event_log); + event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); rc = arm_set_nt_fw_info( #ifdef SPD_opteed - (uintptr_t)event_log, + (uintptr_t)event_log_base, #endif event_log_cur_size, &ns_log_addr); if (rc != 0) { @@ -64,7 +89,7 @@ void bl2_plat_mboot_finish(void) } /* Copy Event Log to Non-secure memory */ - (void)memcpy((void *)ns_log_addr, (const void *)event_log, + (void)memcpy((void *)ns_log_addr, (const void *)event_log_base, event_log_cur_size); /* Ensure that the Event Log is visible in Non-secure memory */ @@ -72,14 +97,14 @@ void bl2_plat_mboot_finish(void) #if defined(SPD_tspd) || defined(SPD_spmd) /* Set Event Log data in TOS_FW_CONFIG */ - rc = arm_set_tos_fw_info((uintptr_t)event_log, + rc = arm_set_tos_fw_info((uintptr_t)event_log_base, event_log_cur_size); if (rc != 0) { ERROR("%s(): Unable to update %s_FW_CONFIG\n", __func__, "TOS"); panic(); } -#endif +#endif /* defined(SPD_tspd) || defined(SPD_spmd) */ - dump_event_log(event_log, event_log_cur_size); + dump_event_log((uint8_t *)event_log_base, event_log_cur_size); } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 33f2e495e..6a2a6f89a 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -11,6 +11,8 @@ #endif #include +#include +#include #include #include @@ -121,8 +123,6 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) /* * Write the Event Log address and its size in the DTB. * - * This function is supposed to be called only by BL2. - * * Returns: * 0 = success * < 0 = error @@ -282,4 +282,87 @@ int arm_set_nt_fw_info( *ns_log_addr = (err < 0) ? 0UL : ns_addr; return err; } + +/* + * This function writes the Event Log address and its size + * in the TB_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL1. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size) +{ + /* + * Read tb_fw_config device tree for Event Log properties + * and write the Event Log address and its size in the DTB + */ + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + uintptr_t tb_fw_cfg_dtb; + int err; + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; + + err = arm_set_event_log_info(tb_fw_cfg_dtb, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + return err; +} + +/* + * This function reads the Event Log address and its size + * properties present in TB_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + * Alongside returns Event Log address and its size. + */ + +int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + int node, rc; + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + void *dtb = (void *)tb_fw_config_info->config_addr; + const char *compatible = "arm,tpm_event_log"; + + /* Assert the node offset point to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, compatible); + if (node < 0) { + WARN("The compatible property '%s'%s", compatible, + " not specified in TB_FW config.\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + + rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr); + if (rc != 0) { + ERROR("%s%s", DTB_PROP_HW_LOG_ADDR, + " not specified in TB_FW config.\n"); + return rc; + } + + rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size); + if (rc != 0) { + ERROR("%s%s", DTB_PROP_HW_LOG_SIZE, + " not specified in TB_FW config.\n"); + } + + return rc; +} #endif /* MEASURED_BOOT */