xref: /rk3399_ARM-atf/plat/arm/common/arm_dyn_cfg_helpers.c (revision 885e26830499284a7718f825579d6ebeb8b6cd89)
1cab0b5b0SSoby Mathew /*
2e6937287SZelalem  * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
3cab0b5b0SSoby Mathew  *
4cab0b5b0SSoby Mathew  * SPDX-License-Identifier: BSD-3-Clause
5cab0b5b0SSoby Mathew  */
6cab0b5b0SSoby Mathew 
7cab0b5b0SSoby Mathew #include <assert.h>
809d40e0eSAntonio Nino Diaz 
9*885e2683SClaus Pedersen #include <common/debug.h>
107b4e1fbbSAlexei Fedorov #if MEASURED_BOOT
117b4e1fbbSAlexei Fedorov #include <common/desc_image_load.h>
127b4e1fbbSAlexei Fedorov #endif
137b4e1fbbSAlexei Fedorov #include <common/fdt_wrappers.h>
147b4e1fbbSAlexei Fedorov 
150500f447SManish V Badarkhe #include <lib/fconf/fconf.h>
160500f447SManish V Badarkhe #include <lib/fconf/fconf_dyn_cfg_getter.h>
17cab0b5b0SSoby Mathew #include <libfdt.h>
1809d40e0eSAntonio Nino Diaz 
19bd9344f6SAntonio Nino Diaz #include <plat/arm/common/arm_dyn_cfg_helpers.h>
20bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
21cab0b5b0SSoby Mathew 
22ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
23ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
241d71ba14SSoby Mathew 
250ab49645SAlexei Fedorov #if MEASURED_BOOT
267b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
277b4e1fbbSAlexei Fedorov /*
287b4e1fbbSAlexei Fedorov  * Currently OP-TEE does not support reading DTBs from Secure memory
297b4e1fbbSAlexei Fedorov  * and this property should be removed when this feature is supported.
307b4e1fbbSAlexei Fedorov  */
317b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_SM_LOG_ADDR	"tpm_event_log_sm_addr"
32eab78e9bSManish V Badarkhe #endif /* SPD_opteed */
337b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
347b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_LOG_SIZE    "tpm_event_log_size"
350ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
360ab49645SAlexei Fedorov 
37cab0b5b0SSoby Mathew /*******************************************************************************
38cab0b5b0SSoby Mathew  * Validate the tb_fw_config is a valid DTB file and returns the node offset
39cab0b5b0SSoby Mathew  * to "arm,tb_fw" property.
40cab0b5b0SSoby Mathew  * Arguments:
41cab0b5b0SSoby Mathew  *	void *dtb - pointer to the TB_FW_CONFIG in memory
42cab0b5b0SSoby Mathew  *	int *node - Returns the node offset to "arm,tb_fw" property if found.
43cab0b5b0SSoby Mathew  *
44cab0b5b0SSoby Mathew  * Returns 0 on success and -1 on error.
45cab0b5b0SSoby Mathew  ******************************************************************************/
46cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
47cab0b5b0SSoby Mathew {
48da5f2745SSoby Mathew 	assert(dtb != NULL);
49da5f2745SSoby Mathew 	assert(node != NULL);
50cab0b5b0SSoby Mathew 
51cab0b5b0SSoby Mathew 	/* Check if the pointer to DT is correct */
52cab0b5b0SSoby Mathew 	if (fdt_check_header(dtb) != 0) {
537b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG");
54cab0b5b0SSoby Mathew 		return -1;
55cab0b5b0SSoby Mathew 	}
56cab0b5b0SSoby Mathew 
57cab0b5b0SSoby Mathew 	/* Assert the node offset point to "arm,tb_fw" compatible property */
58cab0b5b0SSoby Mathew 	*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
59cab0b5b0SSoby Mathew 	if (*node < 0) {
607b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", "arm,tb_fw",
617b4e1fbbSAlexei Fedorov 			" found in the config\n");
62cab0b5b0SSoby Mathew 		return -1;
63cab0b5b0SSoby Mathew 	}
64cab0b5b0SSoby Mathew 
657b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n");
66cab0b5b0SSoby Mathew 	return 0;
67cab0b5b0SSoby Mathew }
68ba597da7SJohn Tsichritzis 
69ba597da7SJohn Tsichritzis /*
70ba597da7SJohn Tsichritzis  * This function writes the Mbed TLS heap address and size in the DTB. When it
71ba597da7SJohn Tsichritzis  * is called, it is guaranteed that a DTB is available. However it is not
72ba597da7SJohn Tsichritzis  * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
73ba597da7SJohn Tsichritzis  * return error code from here and it's the responsibility of the caller to
74ba597da7SJohn Tsichritzis  * determine the action upon error.
75ba597da7SJohn Tsichritzis  *
76ba597da7SJohn Tsichritzis  * This function is supposed to be called only by BL1.
77ba597da7SJohn Tsichritzis  *
78ba597da7SJohn Tsichritzis  * Returns:
79ba597da7SJohn Tsichritzis  *	0 = success
800ab49645SAlexei Fedorov  *     -1 = error
81ba597da7SJohn Tsichritzis  */
82ba597da7SJohn Tsichritzis int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
83ba597da7SJohn Tsichritzis {
840ab49645SAlexei Fedorov 	int dtb_root;
85eab78e9bSManish V Badarkhe 
86ba597da7SJohn Tsichritzis 	/*
87ba597da7SJohn Tsichritzis 	 * Verify that the DTB is valid, before attempting to write to it,
88ba597da7SJohn Tsichritzis 	 * and get the DTB root node.
89ba597da7SJohn Tsichritzis 	 */
900ab49645SAlexei Fedorov 	int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
91ba597da7SJohn Tsichritzis 	if (err < 0) {
927b4e1fbbSAlexei Fedorov 		ERROR("Invalid%s loaded. Unable to get root node\n",
937b4e1fbbSAlexei Fedorov 			" TB_FW_CONFIG");
94ba597da7SJohn Tsichritzis 		return -1;
95ba597da7SJohn Tsichritzis 	}
96ba597da7SJohn Tsichritzis 
97ba597da7SJohn Tsichritzis 	/*
98ba597da7SJohn Tsichritzis 	 * Write the heap address and size in the DTB.
99ba597da7SJohn Tsichritzis 	 *
100ba597da7SJohn Tsichritzis 	 * NOTE: The variables heap_addr and heap_size are corrupted
101ba597da7SJohn Tsichritzis 	 * by the "fdtw_write_inplace_cells" function. After the
102ba597da7SJohn Tsichritzis 	 * function calls they must NOT be reused.
103ba597da7SJohn Tsichritzis 	 */
104ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
105ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
106ba597da7SJohn Tsichritzis 	if (err < 0) {
1077b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1087b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR);
109ba597da7SJohn Tsichritzis 		return -1;
110ba597da7SJohn Tsichritzis 	}
111ba597da7SJohn Tsichritzis 
112ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
113ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
114ba597da7SJohn Tsichritzis 	if (err < 0) {
1157b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1167b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE);
117ba597da7SJohn Tsichritzis 		return -1;
118ba597da7SJohn Tsichritzis 	}
119ba597da7SJohn Tsichritzis 
120ba597da7SJohn Tsichritzis 	return 0;
121ba597da7SJohn Tsichritzis }
1220ab49645SAlexei Fedorov 
1230ab49645SAlexei Fedorov #if MEASURED_BOOT
1240ab49645SAlexei Fedorov /*
1257b4e1fbbSAlexei Fedorov  * Write the Event Log address and its size in the DTB.
1267b4e1fbbSAlexei Fedorov  *
1277b4e1fbbSAlexei Fedorov  * Returns:
1287b4e1fbbSAlexei Fedorov  *	0 = success
1297b4e1fbbSAlexei Fedorov  *    < 0 = error
1307b4e1fbbSAlexei Fedorov  */
1317b4e1fbbSAlexei Fedorov static int arm_set_event_log_info(uintptr_t config_base,
1327b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
1337b4e1fbbSAlexei Fedorov 				  uintptr_t sm_log_addr,
1347b4e1fbbSAlexei Fedorov #endif
1357b4e1fbbSAlexei Fedorov 				  uintptr_t log_addr, size_t log_size)
1367b4e1fbbSAlexei Fedorov {
1377b4e1fbbSAlexei Fedorov 	/* As libfdt uses void *, we can't avoid this cast */
1387b4e1fbbSAlexei Fedorov 	void *dtb = (void *)config_base;
1397b4e1fbbSAlexei Fedorov 	const char *compatible = "arm,tpm_event_log";
1407b4e1fbbSAlexei Fedorov 	int err, node;
1417b4e1fbbSAlexei Fedorov 
1427b4e1fbbSAlexei Fedorov 	/*
1437b4e1fbbSAlexei Fedorov 	 * Verify that the DTB is valid, before attempting to write to it,
1447b4e1fbbSAlexei Fedorov 	 * and get the DTB root node.
1457b4e1fbbSAlexei Fedorov 	 */
1467b4e1fbbSAlexei Fedorov 
1477b4e1fbbSAlexei Fedorov 	/* Check if the pointer to DT is correct */
1487b4e1fbbSAlexei Fedorov 	err = fdt_check_header(dtb);
1497b4e1fbbSAlexei Fedorov 	if (err < 0) {
1507b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed\n");
1517b4e1fbbSAlexei Fedorov 		return err;
1527b4e1fbbSAlexei Fedorov 	}
1537b4e1fbbSAlexei Fedorov 
1547b4e1fbbSAlexei Fedorov 	/* Assert the node offset point to compatible property */
1557b4e1fbbSAlexei Fedorov 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
1567b4e1fbbSAlexei Fedorov 	if (node < 0) {
1577b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", compatible,
1587b4e1fbbSAlexei Fedorov 			" found in the config\n");
1597b4e1fbbSAlexei Fedorov 		return node;
1607b4e1fbbSAlexei Fedorov 	}
1617b4e1fbbSAlexei Fedorov 
1627b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
1637b4e1fbbSAlexei Fedorov 
1647b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
1657b4e1fbbSAlexei Fedorov 	if (sm_log_addr != 0UL) {
1667b4e1fbbSAlexei Fedorov 		err = fdtw_write_inplace_cells(dtb, node,
1677b4e1fbbSAlexei Fedorov 			DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr);
1687b4e1fbbSAlexei Fedorov 		if (err < 0) {
1697b4e1fbbSAlexei Fedorov 			ERROR("%sDTB property '%s'\n",
1707b4e1fbbSAlexei Fedorov 				"Unable to write ", DTB_PROP_HW_SM_LOG_ADDR);
1717b4e1fbbSAlexei Fedorov 			return err;
1727b4e1fbbSAlexei Fedorov 		}
1737b4e1fbbSAlexei Fedorov 	}
1747b4e1fbbSAlexei Fedorov #endif
1757b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
1767b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_ADDR, 2, &log_addr);
1777b4e1fbbSAlexei Fedorov 	if (err < 0) {
1787b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1797b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_ADDR);
1807b4e1fbbSAlexei Fedorov 		return err;
1817b4e1fbbSAlexei Fedorov 	}
1827b4e1fbbSAlexei Fedorov 
1837b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
1847b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_SIZE, 1, &log_size);
1857b4e1fbbSAlexei Fedorov 	if (err < 0) {
1867b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1877b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_SIZE);
1887b4e1fbbSAlexei Fedorov 	} else {
1897b4e1fbbSAlexei Fedorov 		/*
1907b4e1fbbSAlexei Fedorov 		 * Ensure that the info written to the DTB is visible
1917b4e1fbbSAlexei Fedorov 		 * to other images.
1927b4e1fbbSAlexei Fedorov 		 */
1937b4e1fbbSAlexei Fedorov 		flush_dcache_range(config_base, fdt_totalsize(dtb));
1947b4e1fbbSAlexei Fedorov 	}
1957b4e1fbbSAlexei Fedorov 
1967b4e1fbbSAlexei Fedorov 	return err;
1977b4e1fbbSAlexei Fedorov }
1987b4e1fbbSAlexei Fedorov 
1997b4e1fbbSAlexei Fedorov /*
2007b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
2017b4e1fbbSAlexei Fedorov  * in the TOS_FW_CONFIG DTB.
2027b4e1fbbSAlexei Fedorov  *
2037b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
2047b4e1fbbSAlexei Fedorov  *
2057b4e1fbbSAlexei Fedorov  * Returns:
2067b4e1fbbSAlexei Fedorov  *	0 = success
2077b4e1fbbSAlexei Fedorov  *    < 0 = error
2087b4e1fbbSAlexei Fedorov  */
209efa65218SManish V Badarkhe int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size)
2107b4e1fbbSAlexei Fedorov {
211efa65218SManish V Badarkhe 	uintptr_t config_base;
212efa65218SManish V Badarkhe 	const bl_mem_params_node_t *cfg_mem_params;
2137b4e1fbbSAlexei Fedorov 	int err;
2147b4e1fbbSAlexei Fedorov 
2157b4e1fbbSAlexei Fedorov 	assert(log_addr != 0UL);
2167b4e1fbbSAlexei Fedorov 
217efa65218SManish V Badarkhe 	/* Get the config load address and size of TOS_FW_CONFIG */
218efa65218SManish V Badarkhe 	cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
219efa65218SManish V Badarkhe 	assert(cfg_mem_params != NULL);
220efa65218SManish V Badarkhe 
221efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
222efa65218SManish V Badarkhe 
2237b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
2247b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
2257b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2267b4e1fbbSAlexei Fedorov 					0UL,
2277b4e1fbbSAlexei Fedorov #endif
2287b4e1fbbSAlexei Fedorov 					log_addr, log_size);
2297b4e1fbbSAlexei Fedorov 	if (err < 0) {
2307b4e1fbbSAlexei Fedorov 		ERROR("%sEvent Log data to TOS_FW_CONFIG\n",
2317b4e1fbbSAlexei Fedorov 					"Unable to write ");
2327b4e1fbbSAlexei Fedorov 	}
2337b4e1fbbSAlexei Fedorov 
2347b4e1fbbSAlexei Fedorov 	return err;
2357b4e1fbbSAlexei Fedorov }
2367b4e1fbbSAlexei Fedorov 
2377b4e1fbbSAlexei Fedorov /*
2387b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
2397b4e1fbbSAlexei Fedorov  * in the NT_FW_CONFIG DTB.
2407b4e1fbbSAlexei Fedorov  *
2417b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
2427b4e1fbbSAlexei Fedorov  *
2437b4e1fbbSAlexei Fedorov  * Returns:
2447b4e1fbbSAlexei Fedorov  *	0 = success
2457b4e1fbbSAlexei Fedorov  *    < 0 = error
2467b4e1fbbSAlexei Fedorov  */
247efa65218SManish V Badarkhe int arm_set_nt_fw_info(
2487b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2497b4e1fbbSAlexei Fedorov 			uintptr_t log_addr,
2507b4e1fbbSAlexei Fedorov #endif
2517b4e1fbbSAlexei Fedorov 			size_t log_size, uintptr_t *ns_log_addr)
2527b4e1fbbSAlexei Fedorov {
253efa65218SManish V Badarkhe 	uintptr_t config_base;
2547b4e1fbbSAlexei Fedorov 	uintptr_t ns_addr;
2557b4e1fbbSAlexei Fedorov 	const bl_mem_params_node_t *cfg_mem_params;
2567b4e1fbbSAlexei Fedorov 	int err;
2577b4e1fbbSAlexei Fedorov 
2587b4e1fbbSAlexei Fedorov 	assert(ns_log_addr != NULL);
2597b4e1fbbSAlexei Fedorov 
2607b4e1fbbSAlexei Fedorov 	/* Get the config load address and size from NT_FW_CONFIG */
2617b4e1fbbSAlexei Fedorov 	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
2627b4e1fbbSAlexei Fedorov 	assert(cfg_mem_params != NULL);
2637b4e1fbbSAlexei Fedorov 
264efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
265efa65218SManish V Badarkhe 
2667b4e1fbbSAlexei Fedorov 	/* Calculate Event Log address in Non-secure memory */
2677b4e1fbbSAlexei Fedorov 	ns_addr = cfg_mem_params->image_info.image_base +
2687b4e1fbbSAlexei Fedorov 			cfg_mem_params->image_info.image_max_size;
2697b4e1fbbSAlexei Fedorov 
2707b4e1fbbSAlexei Fedorov 	/* Check for memory space */
2717b4e1fbbSAlexei Fedorov 	if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) {
2727b4e1fbbSAlexei Fedorov 		return -1;
2737b4e1fbbSAlexei Fedorov 	}
2747b4e1fbbSAlexei Fedorov 
2757b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
2767b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
2777b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2787b4e1fbbSAlexei Fedorov 					log_addr,
2797b4e1fbbSAlexei Fedorov #endif
2807b4e1fbbSAlexei Fedorov 					ns_addr, log_size);
2817b4e1fbbSAlexei Fedorov 
2827b4e1fbbSAlexei Fedorov 	/* Return Event Log address in Non-secure memory */
2837b4e1fbbSAlexei Fedorov 	*ns_log_addr = (err < 0) ? 0UL : ns_addr;
2847b4e1fbbSAlexei Fedorov 	return err;
2857b4e1fbbSAlexei Fedorov }
2860500f447SManish V Badarkhe 
2870500f447SManish V Badarkhe /*
2880500f447SManish V Badarkhe  * This function writes the Event Log address and its size
2890500f447SManish V Badarkhe  * in the TB_FW_CONFIG DTB.
2900500f447SManish V Badarkhe  *
2910500f447SManish V Badarkhe  * This function is supposed to be called only by BL1.
2920500f447SManish V Badarkhe  *
2930500f447SManish V Badarkhe  * Returns:
2940500f447SManish V Badarkhe  *     0 = success
2950500f447SManish V Badarkhe  *   < 0 = error
2960500f447SManish V Badarkhe  */
2970500f447SManish V Badarkhe int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size)
2980500f447SManish V Badarkhe {
2990500f447SManish V Badarkhe 	/*
3000500f447SManish V Badarkhe 	 * Read tb_fw_config device tree for Event Log properties
3010500f447SManish V Badarkhe 	 * and write the Event Log address and its size in the DTB
3020500f447SManish V Badarkhe 	 */
3030500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
3040500f447SManish V Badarkhe 	uintptr_t tb_fw_cfg_dtb;
3050500f447SManish V Badarkhe 	int err;
3060500f447SManish V Badarkhe 
3070500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
3080500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
3090500f447SManish V Badarkhe 
3100500f447SManish V Badarkhe 	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
3110500f447SManish V Badarkhe 
3120500f447SManish V Badarkhe 	err = arm_set_event_log_info(tb_fw_cfg_dtb,
3130500f447SManish V Badarkhe #ifdef SPD_opteed
3140500f447SManish V Badarkhe 				     0UL,
3150500f447SManish V Badarkhe #endif
3160500f447SManish V Badarkhe 				     log_addr, log_size);
3170500f447SManish V Badarkhe 	return err;
3180500f447SManish V Badarkhe }
3190500f447SManish V Badarkhe 
3200500f447SManish V Badarkhe /*
3210500f447SManish V Badarkhe  * This function reads the Event Log address and its size
3220500f447SManish V Badarkhe  * properties present in TB_FW_CONFIG DTB.
3230500f447SManish V Badarkhe  *
3240500f447SManish V Badarkhe  * This function is supposed to be called only by BL2.
3250500f447SManish V Badarkhe  *
3260500f447SManish V Badarkhe  * Returns:
3270500f447SManish V Badarkhe  *     0 = success
3280500f447SManish V Badarkhe  *   < 0 = error
3290500f447SManish V Badarkhe  * Alongside returns Event Log address and its size.
3300500f447SManish V Badarkhe  */
3310500f447SManish V Badarkhe 
3320500f447SManish V Badarkhe int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size)
3330500f447SManish V Badarkhe {
3340500f447SManish V Badarkhe 	/* As libfdt uses void *, we can't avoid this cast */
3350500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
3360500f447SManish V Badarkhe 	int node, rc;
3370500f447SManish V Badarkhe 
3380500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
3390500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
3400500f447SManish V Badarkhe 
3410500f447SManish V Badarkhe 	void *dtb = (void *)tb_fw_config_info->config_addr;
3420500f447SManish V Badarkhe 	const char *compatible = "arm,tpm_event_log";
3430500f447SManish V Badarkhe 
3440500f447SManish V Badarkhe 	/* Assert the node offset point to compatible property */
3450500f447SManish V Badarkhe 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
3460500f447SManish V Badarkhe 	if (node < 0) {
3470500f447SManish V Badarkhe 		WARN("The compatible property '%s'%s", compatible,
3480500f447SManish V Badarkhe 		     " not specified in TB_FW config.\n");
3490500f447SManish V Badarkhe 		return node;
3500500f447SManish V Badarkhe 	}
3510500f447SManish V Badarkhe 
3520500f447SManish V Badarkhe 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
3530500f447SManish V Badarkhe 
3540500f447SManish V Badarkhe 	rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr);
3550500f447SManish V Badarkhe 	if (rc != 0) {
3560500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_ADDR,
3570500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
3580500f447SManish V Badarkhe 		return rc;
3590500f447SManish V Badarkhe 	}
3600500f447SManish V Badarkhe 
3610500f447SManish V Badarkhe 	rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size);
3620500f447SManish V Badarkhe 	if (rc != 0) {
3630500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
3640500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
3650500f447SManish V Badarkhe 	}
3660500f447SManish V Badarkhe 
3670500f447SManish V Badarkhe 	return rc;
3680500f447SManish V Badarkhe }
3690ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
370