xref: /rk3399_ARM-atf/plat/arm/common/arm_dyn_cfg_helpers.c (revision 0500f4479eb1d0d5ab9e83dac42b633a5ff677dd)
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 
97b4e1fbbSAlexei Fedorov #if MEASURED_BOOT
107b4e1fbbSAlexei Fedorov #include <common/desc_image_load.h>
117b4e1fbbSAlexei Fedorov #endif
127b4e1fbbSAlexei Fedorov #include <common/fdt_wrappers.h>
137b4e1fbbSAlexei Fedorov 
14*0500f447SManish V Badarkhe #include <lib/fconf/fconf.h>
15*0500f447SManish V Badarkhe #include <lib/fconf/fconf_dyn_cfg_getter.h>
16cab0b5b0SSoby Mathew #include <libfdt.h>
1709d40e0eSAntonio Nino Diaz 
18bd9344f6SAntonio Nino Diaz #include <plat/arm/common/arm_dyn_cfg_helpers.h>
19bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
20cab0b5b0SSoby Mathew 
21ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
22ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
231d71ba14SSoby Mathew 
240ab49645SAlexei Fedorov #if MEASURED_BOOT
257b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
267b4e1fbbSAlexei Fedorov /*
277b4e1fbbSAlexei Fedorov  * Currently OP-TEE does not support reading DTBs from Secure memory
287b4e1fbbSAlexei Fedorov  * and this property should be removed when this feature is supported.
297b4e1fbbSAlexei Fedorov  */
307b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_SM_LOG_ADDR	"tpm_event_log_sm_addr"
31eab78e9bSManish V Badarkhe #endif /* SPD_opteed */
327b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_LOG_ADDR	"tpm_event_log_addr"
337b4e1fbbSAlexei Fedorov #define DTB_PROP_HW_LOG_SIZE    "tpm_event_log_size"
340ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
350ab49645SAlexei Fedorov 
36cab0b5b0SSoby Mathew /*******************************************************************************
37cab0b5b0SSoby Mathew  * Validate the tb_fw_config is a valid DTB file and returns the node offset
38cab0b5b0SSoby Mathew  * to "arm,tb_fw" property.
39cab0b5b0SSoby Mathew  * Arguments:
40cab0b5b0SSoby Mathew  *	void *dtb - pointer to the TB_FW_CONFIG in memory
41cab0b5b0SSoby Mathew  *	int *node - Returns the node offset to "arm,tb_fw" property if found.
42cab0b5b0SSoby Mathew  *
43cab0b5b0SSoby Mathew  * Returns 0 on success and -1 on error.
44cab0b5b0SSoby Mathew  ******************************************************************************/
45cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
46cab0b5b0SSoby Mathew {
47da5f2745SSoby Mathew 	assert(dtb != NULL);
48da5f2745SSoby Mathew 	assert(node != NULL);
49cab0b5b0SSoby Mathew 
50cab0b5b0SSoby Mathew 	/* Check if the pointer to DT is correct */
51cab0b5b0SSoby Mathew 	if (fdt_check_header(dtb) != 0) {
527b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG");
53cab0b5b0SSoby Mathew 		return -1;
54cab0b5b0SSoby Mathew 	}
55cab0b5b0SSoby Mathew 
56cab0b5b0SSoby Mathew 	/* Assert the node offset point to "arm,tb_fw" compatible property */
57cab0b5b0SSoby Mathew 	*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
58cab0b5b0SSoby Mathew 	if (*node < 0) {
597b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", "arm,tb_fw",
607b4e1fbbSAlexei Fedorov 			" found in the config\n");
61cab0b5b0SSoby Mathew 		return -1;
62cab0b5b0SSoby Mathew 	}
63cab0b5b0SSoby Mathew 
647b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n");
65cab0b5b0SSoby Mathew 	return 0;
66cab0b5b0SSoby Mathew }
67ba597da7SJohn Tsichritzis 
68ba597da7SJohn Tsichritzis /*
69ba597da7SJohn Tsichritzis  * This function writes the Mbed TLS heap address and size in the DTB. When it
70ba597da7SJohn Tsichritzis  * is called, it is guaranteed that a DTB is available. However it is not
71ba597da7SJohn Tsichritzis  * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
72ba597da7SJohn Tsichritzis  * return error code from here and it's the responsibility of the caller to
73ba597da7SJohn Tsichritzis  * determine the action upon error.
74ba597da7SJohn Tsichritzis  *
75ba597da7SJohn Tsichritzis  * This function is supposed to be called only by BL1.
76ba597da7SJohn Tsichritzis  *
77ba597da7SJohn Tsichritzis  * Returns:
78ba597da7SJohn Tsichritzis  *	0 = success
790ab49645SAlexei Fedorov  *     -1 = error
80ba597da7SJohn Tsichritzis  */
81ba597da7SJohn Tsichritzis int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
82ba597da7SJohn Tsichritzis {
830ab49645SAlexei Fedorov 	int dtb_root;
84eab78e9bSManish V Badarkhe 
85ba597da7SJohn Tsichritzis 	/*
86ba597da7SJohn Tsichritzis 	 * Verify that the DTB is valid, before attempting to write to it,
87ba597da7SJohn Tsichritzis 	 * and get the DTB root node.
88ba597da7SJohn Tsichritzis 	 */
890ab49645SAlexei Fedorov 	int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
90ba597da7SJohn Tsichritzis 	if (err < 0) {
917b4e1fbbSAlexei Fedorov 		ERROR("Invalid%s loaded. Unable to get root node\n",
927b4e1fbbSAlexei Fedorov 			" TB_FW_CONFIG");
93ba597da7SJohn Tsichritzis 		return -1;
94ba597da7SJohn Tsichritzis 	}
95ba597da7SJohn Tsichritzis 
96ba597da7SJohn Tsichritzis 	/*
97ba597da7SJohn Tsichritzis 	 * Write the heap address and size in the DTB.
98ba597da7SJohn Tsichritzis 	 *
99ba597da7SJohn Tsichritzis 	 * NOTE: The variables heap_addr and heap_size are corrupted
100ba597da7SJohn Tsichritzis 	 * by the "fdtw_write_inplace_cells" function. After the
101ba597da7SJohn Tsichritzis 	 * function calls they must NOT be reused.
102ba597da7SJohn Tsichritzis 	 */
103ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
104ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
105ba597da7SJohn Tsichritzis 	if (err < 0) {
1067b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1077b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR);
108ba597da7SJohn Tsichritzis 		return -1;
109ba597da7SJohn Tsichritzis 	}
110ba597da7SJohn Tsichritzis 
111ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
112ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
113ba597da7SJohn Tsichritzis 	if (err < 0) {
1147b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1157b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE);
116ba597da7SJohn Tsichritzis 		return -1;
117ba597da7SJohn Tsichritzis 	}
118ba597da7SJohn Tsichritzis 
119ba597da7SJohn Tsichritzis 	return 0;
120ba597da7SJohn Tsichritzis }
1210ab49645SAlexei Fedorov 
1220ab49645SAlexei Fedorov #if MEASURED_BOOT
1230ab49645SAlexei Fedorov /*
1247b4e1fbbSAlexei Fedorov  * Write the Event Log address and its size in the DTB.
1257b4e1fbbSAlexei Fedorov  *
1267b4e1fbbSAlexei Fedorov  * Returns:
1277b4e1fbbSAlexei Fedorov  *	0 = success
1287b4e1fbbSAlexei Fedorov  *    < 0 = error
1297b4e1fbbSAlexei Fedorov  */
1307b4e1fbbSAlexei Fedorov static int arm_set_event_log_info(uintptr_t config_base,
1317b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
1327b4e1fbbSAlexei Fedorov 				  uintptr_t sm_log_addr,
1337b4e1fbbSAlexei Fedorov #endif
1347b4e1fbbSAlexei Fedorov 				  uintptr_t log_addr, size_t log_size)
1357b4e1fbbSAlexei Fedorov {
1367b4e1fbbSAlexei Fedorov 	/* As libfdt uses void *, we can't avoid this cast */
1377b4e1fbbSAlexei Fedorov 	void *dtb = (void *)config_base;
1387b4e1fbbSAlexei Fedorov 	const char *compatible = "arm,tpm_event_log";
1397b4e1fbbSAlexei Fedorov 	int err, node;
1407b4e1fbbSAlexei Fedorov 
1417b4e1fbbSAlexei Fedorov 	/*
1427b4e1fbbSAlexei Fedorov 	 * Verify that the DTB is valid, before attempting to write to it,
1437b4e1fbbSAlexei Fedorov 	 * and get the DTB root node.
1447b4e1fbbSAlexei Fedorov 	 */
1457b4e1fbbSAlexei Fedorov 
1467b4e1fbbSAlexei Fedorov 	/* Check if the pointer to DT is correct */
1477b4e1fbbSAlexei Fedorov 	err = fdt_check_header(dtb);
1487b4e1fbbSAlexei Fedorov 	if (err < 0) {
1497b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed\n");
1507b4e1fbbSAlexei Fedorov 		return err;
1517b4e1fbbSAlexei Fedorov 	}
1527b4e1fbbSAlexei Fedorov 
1537b4e1fbbSAlexei Fedorov 	/* Assert the node offset point to compatible property */
1547b4e1fbbSAlexei Fedorov 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
1557b4e1fbbSAlexei Fedorov 	if (node < 0) {
1567b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", compatible,
1577b4e1fbbSAlexei Fedorov 			" found in the config\n");
1587b4e1fbbSAlexei Fedorov 		return node;
1597b4e1fbbSAlexei Fedorov 	}
1607b4e1fbbSAlexei Fedorov 
1617b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
1627b4e1fbbSAlexei Fedorov 
1637b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
1647b4e1fbbSAlexei Fedorov 	if (sm_log_addr != 0UL) {
1657b4e1fbbSAlexei Fedorov 		err = fdtw_write_inplace_cells(dtb, node,
1667b4e1fbbSAlexei Fedorov 			DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr);
1677b4e1fbbSAlexei Fedorov 		if (err < 0) {
1687b4e1fbbSAlexei Fedorov 			ERROR("%sDTB property '%s'\n",
1697b4e1fbbSAlexei Fedorov 				"Unable to write ", DTB_PROP_HW_SM_LOG_ADDR);
1707b4e1fbbSAlexei Fedorov 			return err;
1717b4e1fbbSAlexei Fedorov 		}
1727b4e1fbbSAlexei Fedorov 	}
1737b4e1fbbSAlexei Fedorov #endif
1747b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
1757b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_ADDR, 2, &log_addr);
1767b4e1fbbSAlexei Fedorov 	if (err < 0) {
1777b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1787b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_ADDR);
1797b4e1fbbSAlexei Fedorov 		return err;
1807b4e1fbbSAlexei Fedorov 	}
1817b4e1fbbSAlexei Fedorov 
1827b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
1837b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_SIZE, 1, &log_size);
1847b4e1fbbSAlexei Fedorov 	if (err < 0) {
1857b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1867b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_SIZE);
1877b4e1fbbSAlexei Fedorov 	} else {
1887b4e1fbbSAlexei Fedorov 		/*
1897b4e1fbbSAlexei Fedorov 		 * Ensure that the info written to the DTB is visible
1907b4e1fbbSAlexei Fedorov 		 * to other images.
1917b4e1fbbSAlexei Fedorov 		 */
1927b4e1fbbSAlexei Fedorov 		flush_dcache_range(config_base, fdt_totalsize(dtb));
1937b4e1fbbSAlexei Fedorov 	}
1947b4e1fbbSAlexei Fedorov 
1957b4e1fbbSAlexei Fedorov 	return err;
1967b4e1fbbSAlexei Fedorov }
1977b4e1fbbSAlexei Fedorov 
1987b4e1fbbSAlexei Fedorov /*
1997b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
2007b4e1fbbSAlexei Fedorov  * in the TOS_FW_CONFIG DTB.
2017b4e1fbbSAlexei Fedorov  *
2027b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
2037b4e1fbbSAlexei Fedorov  *
2047b4e1fbbSAlexei Fedorov  * Returns:
2057b4e1fbbSAlexei Fedorov  *	0 = success
2067b4e1fbbSAlexei Fedorov  *    < 0 = error
2077b4e1fbbSAlexei Fedorov  */
208efa65218SManish V Badarkhe int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size)
2097b4e1fbbSAlexei Fedorov {
210efa65218SManish V Badarkhe 	uintptr_t config_base;
211efa65218SManish V Badarkhe 	const bl_mem_params_node_t *cfg_mem_params;
2127b4e1fbbSAlexei Fedorov 	int err;
2137b4e1fbbSAlexei Fedorov 
2147b4e1fbbSAlexei Fedorov 	assert(log_addr != 0UL);
2157b4e1fbbSAlexei Fedorov 
216efa65218SManish V Badarkhe 	/* Get the config load address and size of TOS_FW_CONFIG */
217efa65218SManish V Badarkhe 	cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
218efa65218SManish V Badarkhe 	assert(cfg_mem_params != NULL);
219efa65218SManish V Badarkhe 
220efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
221efa65218SManish V Badarkhe 
2227b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
2237b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
2247b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2257b4e1fbbSAlexei Fedorov 					0UL,
2267b4e1fbbSAlexei Fedorov #endif
2277b4e1fbbSAlexei Fedorov 					log_addr, log_size);
2287b4e1fbbSAlexei Fedorov 	if (err < 0) {
2297b4e1fbbSAlexei Fedorov 		ERROR("%sEvent Log data to TOS_FW_CONFIG\n",
2307b4e1fbbSAlexei Fedorov 					"Unable to write ");
2317b4e1fbbSAlexei Fedorov 	}
2327b4e1fbbSAlexei Fedorov 
2337b4e1fbbSAlexei Fedorov 	return err;
2347b4e1fbbSAlexei Fedorov }
2357b4e1fbbSAlexei Fedorov 
2367b4e1fbbSAlexei Fedorov /*
2377b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
2387b4e1fbbSAlexei Fedorov  * in the NT_FW_CONFIG DTB.
2397b4e1fbbSAlexei Fedorov  *
2407b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
2417b4e1fbbSAlexei Fedorov  *
2427b4e1fbbSAlexei Fedorov  * Returns:
2437b4e1fbbSAlexei Fedorov  *	0 = success
2447b4e1fbbSAlexei Fedorov  *    < 0 = error
2457b4e1fbbSAlexei Fedorov  */
246efa65218SManish V Badarkhe int arm_set_nt_fw_info(
2477b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2487b4e1fbbSAlexei Fedorov 			uintptr_t log_addr,
2497b4e1fbbSAlexei Fedorov #endif
2507b4e1fbbSAlexei Fedorov 			size_t log_size, uintptr_t *ns_log_addr)
2517b4e1fbbSAlexei Fedorov {
252efa65218SManish V Badarkhe 	uintptr_t config_base;
2537b4e1fbbSAlexei Fedorov 	uintptr_t ns_addr;
2547b4e1fbbSAlexei Fedorov 	const bl_mem_params_node_t *cfg_mem_params;
2557b4e1fbbSAlexei Fedorov 	int err;
2567b4e1fbbSAlexei Fedorov 
2577b4e1fbbSAlexei Fedorov 	assert(ns_log_addr != NULL);
2587b4e1fbbSAlexei Fedorov 
2597b4e1fbbSAlexei Fedorov 	/* Get the config load address and size from NT_FW_CONFIG */
2607b4e1fbbSAlexei Fedorov 	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
2617b4e1fbbSAlexei Fedorov 	assert(cfg_mem_params != NULL);
2627b4e1fbbSAlexei Fedorov 
263efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
264efa65218SManish V Badarkhe 
2657b4e1fbbSAlexei Fedorov 	/* Calculate Event Log address in Non-secure memory */
2667b4e1fbbSAlexei Fedorov 	ns_addr = cfg_mem_params->image_info.image_base +
2677b4e1fbbSAlexei Fedorov 			cfg_mem_params->image_info.image_max_size;
2687b4e1fbbSAlexei Fedorov 
2697b4e1fbbSAlexei Fedorov 	/* Check for memory space */
2707b4e1fbbSAlexei Fedorov 	if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) {
2717b4e1fbbSAlexei Fedorov 		return -1;
2727b4e1fbbSAlexei Fedorov 	}
2737b4e1fbbSAlexei Fedorov 
2747b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
2757b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
2767b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2777b4e1fbbSAlexei Fedorov 					log_addr,
2787b4e1fbbSAlexei Fedorov #endif
2797b4e1fbbSAlexei Fedorov 					ns_addr, log_size);
2807b4e1fbbSAlexei Fedorov 
2817b4e1fbbSAlexei Fedorov 	/* Return Event Log address in Non-secure memory */
2827b4e1fbbSAlexei Fedorov 	*ns_log_addr = (err < 0) ? 0UL : ns_addr;
2837b4e1fbbSAlexei Fedorov 	return err;
2847b4e1fbbSAlexei Fedorov }
285*0500f447SManish V Badarkhe 
286*0500f447SManish V Badarkhe /*
287*0500f447SManish V Badarkhe  * This function writes the Event Log address and its size
288*0500f447SManish V Badarkhe  * in the TB_FW_CONFIG DTB.
289*0500f447SManish V Badarkhe  *
290*0500f447SManish V Badarkhe  * This function is supposed to be called only by BL1.
291*0500f447SManish V Badarkhe  *
292*0500f447SManish V Badarkhe  * Returns:
293*0500f447SManish V Badarkhe  *     0 = success
294*0500f447SManish V Badarkhe  *   < 0 = error
295*0500f447SManish V Badarkhe  */
296*0500f447SManish V Badarkhe int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size)
297*0500f447SManish V Badarkhe {
298*0500f447SManish V Badarkhe 	/*
299*0500f447SManish V Badarkhe 	 * Read tb_fw_config device tree for Event Log properties
300*0500f447SManish V Badarkhe 	 * and write the Event Log address and its size in the DTB
301*0500f447SManish V Badarkhe 	 */
302*0500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
303*0500f447SManish V Badarkhe 	uintptr_t tb_fw_cfg_dtb;
304*0500f447SManish V Badarkhe 	int err;
305*0500f447SManish V Badarkhe 
306*0500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
307*0500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
308*0500f447SManish V Badarkhe 
309*0500f447SManish V Badarkhe 	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
310*0500f447SManish V Badarkhe 
311*0500f447SManish V Badarkhe 	err = arm_set_event_log_info(tb_fw_cfg_dtb,
312*0500f447SManish V Badarkhe #ifdef SPD_opteed
313*0500f447SManish V Badarkhe 				     0UL,
314*0500f447SManish V Badarkhe #endif
315*0500f447SManish V Badarkhe 				     log_addr, log_size);
316*0500f447SManish V Badarkhe 	return err;
317*0500f447SManish V Badarkhe }
318*0500f447SManish V Badarkhe 
319*0500f447SManish V Badarkhe /*
320*0500f447SManish V Badarkhe  * This function reads the Event Log address and its size
321*0500f447SManish V Badarkhe  * properties present in TB_FW_CONFIG DTB.
322*0500f447SManish V Badarkhe  *
323*0500f447SManish V Badarkhe  * This function is supposed to be called only by BL2.
324*0500f447SManish V Badarkhe  *
325*0500f447SManish V Badarkhe  * Returns:
326*0500f447SManish V Badarkhe  *     0 = success
327*0500f447SManish V Badarkhe  *   < 0 = error
328*0500f447SManish V Badarkhe  * Alongside returns Event Log address and its size.
329*0500f447SManish V Badarkhe  */
330*0500f447SManish V Badarkhe 
331*0500f447SManish V Badarkhe int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size)
332*0500f447SManish V Badarkhe {
333*0500f447SManish V Badarkhe 	/* As libfdt uses void *, we can't avoid this cast */
334*0500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
335*0500f447SManish V Badarkhe 	int node, rc;
336*0500f447SManish V Badarkhe 
337*0500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
338*0500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
339*0500f447SManish V Badarkhe 
340*0500f447SManish V Badarkhe 	void *dtb = (void *)tb_fw_config_info->config_addr;
341*0500f447SManish V Badarkhe 	const char *compatible = "arm,tpm_event_log";
342*0500f447SManish V Badarkhe 
343*0500f447SManish V Badarkhe 	/* Assert the node offset point to compatible property */
344*0500f447SManish V Badarkhe 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
345*0500f447SManish V Badarkhe 	if (node < 0) {
346*0500f447SManish V Badarkhe 		WARN("The compatible property '%s'%s", compatible,
347*0500f447SManish V Badarkhe 		     " not specified in TB_FW config.\n");
348*0500f447SManish V Badarkhe 		return node;
349*0500f447SManish V Badarkhe 	}
350*0500f447SManish V Badarkhe 
351*0500f447SManish V Badarkhe 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
352*0500f447SManish V Badarkhe 
353*0500f447SManish V Badarkhe 	rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr);
354*0500f447SManish V Badarkhe 	if (rc != 0) {
355*0500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_ADDR,
356*0500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
357*0500f447SManish V Badarkhe 		return rc;
358*0500f447SManish V Badarkhe 	}
359*0500f447SManish V Badarkhe 
360*0500f447SManish V Badarkhe 	rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size);
361*0500f447SManish V Badarkhe 	if (rc != 0) {
362*0500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
363*0500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
364*0500f447SManish V Badarkhe 	}
365*0500f447SManish V Badarkhe 
366*0500f447SManish V Badarkhe 	return rc;
367*0500f447SManish V Badarkhe }
3680ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
369