feat(plat/fvp): pass Event Log addr and size from BL1 to BL2
Introduced functions to set and get Event log information
(tpm_event_log address and its size).
In FVP platform case, measured boot with Event Log backend flow
work as below
1. event_log_init function called by BL1 to initialize Event Log
module
2. arm_set_tb_fw_info function called by BL1 to set the
'tpm_event_log_addr' and 'tpm_event_log_size' properties
in tb_fw_config
3. arm_get_tb_fw_info function called by BL2 to get tpm Event Log
parameters set by BL1. These parameters used by the BL2 to
extend the tpm Event Log records, and use these parameters
to initialize Event Log using event_log_init function
4. arm_set_nt_fw_info and arm_set_tos_fw_info function called by
BL2 to set 'tpm_event_log' address and its size properties in
nt_fw_config and tos_fw_config respectively
Alongside, this patch created a separate instances of plat_mboot_init
and plat_mboot_finish APIs for BL1 and BL2.
This patch is tested using the existing measured boot test configuration
in jenkins CI.
Change-Id: Ib9eca092afe580df014541c937868f921dff9c37
Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 5765226..9618700 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -260,6 +260,8 @@
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 15ea059..8815b74 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 <stdint.h>
#include <drivers/measured_boot/event_log/event_log.h>
+#include <plat/arm/common/plat_arm.h>
/* Event Log data */
static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE];
@@ -21,13 +22,23 @@
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 f5d829a..16e8d79 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 <plat/arm/common/plat_arm.h>
/* 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 @@
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 @@
/* 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 @@
}
/* 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 @@
#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 33f2e49..6a2a6f8 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 <common/fdt_wrappers.h>
+#include <lib/fconf/fconf.h>
+#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <libfdt.h>
#include <plat/arm/common/arm_dyn_cfg_helpers.h>
@@ -121,8 +123,6 @@
/*
* 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 @@
*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 */