xref: /rk3399_ARM-atf/plat/arm/common/arm_dyn_cfg_helpers.c (revision 10f6ccdc2893c3b4d39d2641bc47ca1c14e48d28)
1cab0b5b0SSoby Mathew /*
21f47a713STamas Ban  * Copyright (c) 2018-2024, 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 
9885e2683SClaus 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"
351cf3e2f0SManish V Badarkhe #define DTB_PROP_HW_LOG_MAX_SIZE	"tpm_event_log_max_size"
360ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
370ab49645SAlexei Fedorov 
381cf3e2f0SManish V Badarkhe static size_t event_log_max_size __unused;
391cf3e2f0SManish V Badarkhe 
40cab0b5b0SSoby Mathew /*******************************************************************************
41cab0b5b0SSoby Mathew  * Validate the tb_fw_config is a valid DTB file and returns the node offset
42cab0b5b0SSoby Mathew  * to "arm,tb_fw" property.
43cab0b5b0SSoby Mathew  * Arguments:
44cab0b5b0SSoby Mathew  *	void *dtb - pointer to the TB_FW_CONFIG in memory
45cab0b5b0SSoby Mathew  *	int *node - Returns the node offset to "arm,tb_fw" property if found.
46cab0b5b0SSoby Mathew  *
47cab0b5b0SSoby Mathew  * Returns 0 on success and -1 on error.
48cab0b5b0SSoby Mathew  ******************************************************************************/
49cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
50cab0b5b0SSoby Mathew {
51da5f2745SSoby Mathew 	assert(dtb != NULL);
52da5f2745SSoby Mathew 	assert(node != NULL);
53cab0b5b0SSoby Mathew 
54cab0b5b0SSoby Mathew 	/* Check if the pointer to DT is correct */
55cab0b5b0SSoby Mathew 	if (fdt_check_header(dtb) != 0) {
567b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG");
57cab0b5b0SSoby Mathew 		return -1;
58cab0b5b0SSoby Mathew 	}
59cab0b5b0SSoby Mathew 
60cab0b5b0SSoby Mathew 	/* Assert the node offset point to "arm,tb_fw" compatible property */
61cab0b5b0SSoby Mathew 	*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
62cab0b5b0SSoby Mathew 	if (*node < 0) {
637b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", "arm,tb_fw",
647b4e1fbbSAlexei Fedorov 			" found in the config\n");
65cab0b5b0SSoby Mathew 		return -1;
66cab0b5b0SSoby Mathew 	}
67cab0b5b0SSoby Mathew 
687b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n");
69cab0b5b0SSoby Mathew 	return 0;
70cab0b5b0SSoby Mathew }
71ba597da7SJohn Tsichritzis 
72ba597da7SJohn Tsichritzis /*
73ba597da7SJohn Tsichritzis  * This function writes the Mbed TLS heap address and size in the DTB. When it
74ba597da7SJohn Tsichritzis  * is called, it is guaranteed that a DTB is available. However it is not
75ba597da7SJohn Tsichritzis  * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
76ba597da7SJohn Tsichritzis  * return error code from here and it's the responsibility of the caller to
77ba597da7SJohn Tsichritzis  * determine the action upon error.
78ba597da7SJohn Tsichritzis  *
79ba597da7SJohn Tsichritzis  * This function is supposed to be called only by BL1.
80ba597da7SJohn Tsichritzis  *
81ba597da7SJohn Tsichritzis  * Returns:
82ba597da7SJohn Tsichritzis  *	0 = success
830ab49645SAlexei Fedorov  *     -1 = error
84ba597da7SJohn Tsichritzis  */
85ba597da7SJohn Tsichritzis int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
86ba597da7SJohn Tsichritzis {
870ab49645SAlexei Fedorov 	int dtb_root;
88eab78e9bSManish V Badarkhe 
89ba597da7SJohn Tsichritzis 	/*
90ba597da7SJohn Tsichritzis 	 * Verify that the DTB is valid, before attempting to write to it,
91ba597da7SJohn Tsichritzis 	 * and get the DTB root node.
92ba597da7SJohn Tsichritzis 	 */
930ab49645SAlexei Fedorov 	int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
94ba597da7SJohn Tsichritzis 	if (err < 0) {
957b4e1fbbSAlexei Fedorov 		ERROR("Invalid%s loaded. Unable to get root node\n",
967b4e1fbbSAlexei Fedorov 			" TB_FW_CONFIG");
97ba597da7SJohn Tsichritzis 		return -1;
98ba597da7SJohn Tsichritzis 	}
99ba597da7SJohn Tsichritzis 
100ba597da7SJohn Tsichritzis 	/*
101ba597da7SJohn Tsichritzis 	 * Write the heap address and size in the DTB.
102ba597da7SJohn Tsichritzis 	 *
103ba597da7SJohn Tsichritzis 	 * NOTE: The variables heap_addr and heap_size are corrupted
104ba597da7SJohn Tsichritzis 	 * by the "fdtw_write_inplace_cells" function. After the
105ba597da7SJohn Tsichritzis 	 * function calls they must NOT be reused.
106ba597da7SJohn Tsichritzis 	 */
107ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
108ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
109ba597da7SJohn Tsichritzis 	if (err < 0) {
1107b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1117b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR);
112ba597da7SJohn Tsichritzis 		return -1;
113ba597da7SJohn Tsichritzis 	}
114ba597da7SJohn Tsichritzis 
115ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
116ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
117ba597da7SJohn Tsichritzis 	if (err < 0) {
1187b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
1197b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE);
120ba597da7SJohn Tsichritzis 		return -1;
121ba597da7SJohn Tsichritzis 	}
122ba597da7SJohn Tsichritzis 
123ba597da7SJohn Tsichritzis 	return 0;
124ba597da7SJohn Tsichritzis }
1250ab49645SAlexei Fedorov 
1260ab49645SAlexei Fedorov #if MEASURED_BOOT
1271f47a713STamas Ban #if DICE_PROTECTION_ENVIRONMENT
1281f47a713STamas Ban 
1291f47a713STamas Ban #include <common/desc_image_load.h>
1301f47a713STamas Ban 
1311f47a713STamas Ban #define DTB_PROP_DPE_CTX_HANDLE		"dpe_ctx_handle"
1321f47a713STamas Ban 
1331f47a713STamas Ban static int arm_set_dpe_context_handle(uintptr_t config_base,
1341f47a713STamas Ban 				      int *ctx_handle)
1351f47a713STamas Ban {
1361f47a713STamas Ban 	/* As libfdt uses void *, we can't avoid this cast */
1371f47a713STamas Ban 	void *dtb = (void *)config_base;
1381f47a713STamas Ban 	const char *compatible = "arm,dpe_ctx_handle";
1391f47a713STamas Ban 	int err, node;
1401f47a713STamas Ban 
1411f47a713STamas Ban 	/*
1421f47a713STamas Ban 	 * Verify that the DTB is valid, before attempting to write to it,
1431f47a713STamas Ban 	 * and get the DTB root node.
1441f47a713STamas Ban 	 */
1451f47a713STamas Ban 
1461f47a713STamas Ban 	/* Check if the pointer to DT is correct */
1471f47a713STamas Ban 	err = fdt_check_header(dtb);
1481f47a713STamas Ban 	if (err < 0) {
1491f47a713STamas Ban 		WARN("Invalid DTB file passed\n");
1501f47a713STamas Ban 		return err;
1511f47a713STamas Ban 	}
1521f47a713STamas Ban 
1531f47a713STamas Ban 	/* Assert the node offset point to compatible property */
1541f47a713STamas Ban 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
1551f47a713STamas Ban 	if (node < 0) {
1561f47a713STamas Ban 		WARN("The compatible property '%s' not%s", compatible,
1571f47a713STamas Ban 			" found in the config\n");
1581f47a713STamas Ban 		return node;
1591f47a713STamas Ban 	}
1601f47a713STamas Ban 
1611f47a713STamas Ban 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
1621f47a713STamas Ban 
1631f47a713STamas Ban 	err = fdtw_write_inplace_cells(dtb, node,
1641f47a713STamas Ban 		DTB_PROP_DPE_CTX_HANDLE, 1, ctx_handle);
1651f47a713STamas Ban 	if (err < 0) {
1661f47a713STamas Ban 		ERROR("%sDTB property '%s'\n",
1671f47a713STamas Ban 			"Unable to write ", DTB_PROP_DPE_CTX_HANDLE);
1681f47a713STamas Ban 	} else {
1691f47a713STamas Ban 		/*
1701f47a713STamas Ban 		 * Ensure that the info written to the DTB is visible
1711f47a713STamas Ban 		 * to other images.
1721f47a713STamas Ban 		 */
1731f47a713STamas Ban 		flush_dcache_range(config_base, fdt_totalsize(dtb));
1741f47a713STamas Ban 	}
1751f47a713STamas Ban 
1761f47a713STamas Ban 	return err;
1771f47a713STamas Ban }
1781f47a713STamas Ban 
1791f47a713STamas Ban /*
1801f47a713STamas Ban  * This function writes the DPE context handle value to the NT_FW_CONFIG DTB.
1811f47a713STamas Ban  *
1821f47a713STamas Ban  * This function is supposed to be called only by BL2.
1831f47a713STamas Ban  *
1841f47a713STamas Ban  * Returns:
1851f47a713STamas Ban  *	0 = success
1861f47a713STamas Ban  *    < 0 = error
1871f47a713STamas Ban  */
1881f47a713STamas Ban int arm_set_nt_fw_info(int *ctx_handle)
1891f47a713STamas Ban {
1901f47a713STamas Ban 	uintptr_t config_base;
1911f47a713STamas Ban 	const bl_mem_params_node_t *cfg_mem_params;
1921f47a713STamas Ban 
1931f47a713STamas Ban 	/* Get the config load address and size from NT_FW_CONFIG */
1941f47a713STamas Ban 	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
1951f47a713STamas Ban 	assert(cfg_mem_params != NULL);
1961f47a713STamas Ban 
1971f47a713STamas Ban 	config_base = cfg_mem_params->image_info.image_base;
1981f47a713STamas Ban 
1991f47a713STamas Ban 	/* Write the context handle value in the DTB */
2001f47a713STamas Ban 	return arm_set_dpe_context_handle(config_base, ctx_handle);
2011f47a713STamas Ban }
2021f47a713STamas Ban 
2031f47a713STamas Ban /*
2041f47a713STamas Ban  * This function writes the DPE context handle value to the TB_FW_CONFIG DTB.
2051f47a713STamas Ban  *
2061f47a713STamas Ban  * This function is supposed to be called only by BL1.
2071f47a713STamas Ban  *
2081f47a713STamas Ban  * Returns:
2091f47a713STamas Ban  *	0 = success
2101f47a713STamas Ban  *    < 0 = error
2111f47a713STamas Ban  */
2121f47a713STamas Ban int arm_set_tb_fw_info(int *ctx_handle)
2131f47a713STamas Ban {
2141f47a713STamas Ban 	/*
2151f47a713STamas Ban 	 * Read tb_fw_config device tree for Event Log properties
2161f47a713STamas Ban 	 * and write the Event Log address and its size in the DTB
2171f47a713STamas Ban 	 */
2181f47a713STamas Ban 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
2191f47a713STamas Ban 	uintptr_t tb_fw_cfg_dtb;
2201f47a713STamas Ban 
2211f47a713STamas Ban 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
2221f47a713STamas Ban 	assert(tb_fw_config_info != NULL);
2231f47a713STamas Ban 
2241f47a713STamas Ban 	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
2251f47a713STamas Ban 
2261f47a713STamas Ban 	/* Write the context handle value in the DTB */
2271f47a713STamas Ban 	return arm_set_dpe_context_handle(tb_fw_cfg_dtb, ctx_handle);
2281f47a713STamas Ban }
2291f47a713STamas Ban 
2301f47a713STamas Ban /*
2311f47a713STamas Ban  * This function reads the initial DPE context handle from TB_FW_CONFIG DTB.
2321f47a713STamas Ban  *
2331f47a713STamas Ban  * This function is supposed to be called only by BL2.
2341f47a713STamas Ban  *
2351f47a713STamas Ban  * Returns:
2361f47a713STamas Ban  *	0 = success
2371f47a713STamas Ban  *    < 0 = error
2381f47a713STamas Ban  */
2391f47a713STamas Ban 
2401f47a713STamas Ban int arm_get_tb_fw_info(int *ctx_handle)
2411f47a713STamas Ban {
2421f47a713STamas Ban 	/* As libfdt uses void *, we can't avoid this cast */
2431f47a713STamas Ban 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
2441f47a713STamas Ban 	int node, rc;
2451f47a713STamas Ban 
2461f47a713STamas Ban 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
2471f47a713STamas Ban 	assert(tb_fw_config_info != NULL);
2481f47a713STamas Ban 
2491f47a713STamas Ban 	void *dtb = (void *)tb_fw_config_info->config_addr;
2501f47a713STamas Ban 	const char *compatible = "arm,dpe_ctx_handle";
2511f47a713STamas Ban 
2521f47a713STamas Ban 	/* Assert the node offset point to compatible property */
2531f47a713STamas Ban 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
2541f47a713STamas Ban 	if (node < 0) {
2551f47a713STamas Ban 		WARN("The compatible property '%s'%s", compatible,
2561f47a713STamas Ban 		     " not specified in TB_FW config.\n");
2571f47a713STamas Ban 		return node;
2581f47a713STamas Ban 	}
2591f47a713STamas Ban 
2601f47a713STamas Ban 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
2611f47a713STamas Ban 
2621f47a713STamas Ban 	rc = fdt_read_uint32(dtb, node, DTB_PROP_DPE_CTX_HANDLE, (uint32_t *)ctx_handle);
2631f47a713STamas Ban 	if (rc != 0) {
2641f47a713STamas Ban 		ERROR("%s%s", DTB_PROP_DPE_CTX_HANDLE,
2651f47a713STamas Ban 		      " not specified in TB_FW config.\n");
2661f47a713STamas Ban 	}
2671f47a713STamas Ban 
2681f47a713STamas Ban 	return rc;
2691f47a713STamas Ban }
2701f47a713STamas Ban #else
2710ab49645SAlexei Fedorov /*
2727b4e1fbbSAlexei Fedorov  * Write the Event Log address and its size in the DTB.
2737b4e1fbbSAlexei Fedorov  *
2747b4e1fbbSAlexei Fedorov  * Returns:
2757b4e1fbbSAlexei Fedorov  *	0 = success
2767b4e1fbbSAlexei Fedorov  *    < 0 = error
2777b4e1fbbSAlexei Fedorov  */
2787b4e1fbbSAlexei Fedorov static int arm_set_event_log_info(uintptr_t config_base,
2797b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
2807b4e1fbbSAlexei Fedorov 				  uintptr_t sm_log_addr,
2817b4e1fbbSAlexei Fedorov #endif
2827b4e1fbbSAlexei Fedorov 				  uintptr_t log_addr, size_t log_size)
2837b4e1fbbSAlexei Fedorov {
2847b4e1fbbSAlexei Fedorov 	/* As libfdt uses void *, we can't avoid this cast */
2857b4e1fbbSAlexei Fedorov 	void *dtb = (void *)config_base;
2867b4e1fbbSAlexei Fedorov 	const char *compatible = "arm,tpm_event_log";
2877b4e1fbbSAlexei Fedorov 	int err, node;
2887b4e1fbbSAlexei Fedorov 
2897b4e1fbbSAlexei Fedorov 	/*
2907b4e1fbbSAlexei Fedorov 	 * Verify that the DTB is valid, before attempting to write to it,
2917b4e1fbbSAlexei Fedorov 	 * and get the DTB root node.
2927b4e1fbbSAlexei Fedorov 	 */
2937b4e1fbbSAlexei Fedorov 
2947b4e1fbbSAlexei Fedorov 	/* Check if the pointer to DT is correct */
2957b4e1fbbSAlexei Fedorov 	err = fdt_check_header(dtb);
2967b4e1fbbSAlexei Fedorov 	if (err < 0) {
2977b4e1fbbSAlexei Fedorov 		WARN("Invalid DTB file passed\n");
2987b4e1fbbSAlexei Fedorov 		return err;
2997b4e1fbbSAlexei Fedorov 	}
3007b4e1fbbSAlexei Fedorov 
3017b4e1fbbSAlexei Fedorov 	/* Assert the node offset point to compatible property */
3027b4e1fbbSAlexei Fedorov 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
3037b4e1fbbSAlexei Fedorov 	if (node < 0) {
3047b4e1fbbSAlexei Fedorov 		WARN("The compatible property '%s' not%s", compatible,
3057b4e1fbbSAlexei Fedorov 			" found in the config\n");
3067b4e1fbbSAlexei Fedorov 		return node;
3077b4e1fbbSAlexei Fedorov 	}
3087b4e1fbbSAlexei Fedorov 
3097b4e1fbbSAlexei Fedorov 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
3107b4e1fbbSAlexei Fedorov 
3117b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
3127b4e1fbbSAlexei Fedorov 	if (sm_log_addr != 0UL) {
3137b4e1fbbSAlexei Fedorov 		err = fdtw_write_inplace_cells(dtb, node,
3147b4e1fbbSAlexei Fedorov 			DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr);
3157b4e1fbbSAlexei Fedorov 		if (err < 0) {
3167b4e1fbbSAlexei Fedorov 			ERROR("%sDTB property '%s'\n",
3177b4e1fbbSAlexei Fedorov 				"Unable to write ", DTB_PROP_HW_SM_LOG_ADDR);
3187b4e1fbbSAlexei Fedorov 			return err;
3197b4e1fbbSAlexei Fedorov 		}
3207b4e1fbbSAlexei Fedorov 	}
3217b4e1fbbSAlexei Fedorov #endif
3227b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
3237b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_ADDR, 2, &log_addr);
3247b4e1fbbSAlexei Fedorov 	if (err < 0) {
3257b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
3267b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_ADDR);
3277b4e1fbbSAlexei Fedorov 		return err;
3287b4e1fbbSAlexei Fedorov 	}
3297b4e1fbbSAlexei Fedorov 
3301cf3e2f0SManish V Badarkhe 	assert(event_log_max_size != 0U);
3311cf3e2f0SManish V Badarkhe 	err = fdtw_write_inplace_cells(dtb, node,
3321cf3e2f0SManish V Badarkhe 				       DTB_PROP_HW_LOG_MAX_SIZE, 1,
3331cf3e2f0SManish V Badarkhe 				       &event_log_max_size);
3341cf3e2f0SManish V Badarkhe 	if (err < 0) {
3351cf3e2f0SManish V Badarkhe 		ERROR("%sDTB property '%s'\n",
3361cf3e2f0SManish V Badarkhe 		      "Unable to write ", DTB_PROP_HW_LOG_MAX_SIZE);
3371cf3e2f0SManish V Badarkhe 		return err;
3381cf3e2f0SManish V Badarkhe 	}
3391cf3e2f0SManish V Badarkhe 
3407b4e1fbbSAlexei Fedorov 	err = fdtw_write_inplace_cells(dtb, node,
3417b4e1fbbSAlexei Fedorov 		DTB_PROP_HW_LOG_SIZE, 1, &log_size);
3427b4e1fbbSAlexei Fedorov 	if (err < 0) {
3437b4e1fbbSAlexei Fedorov 		ERROR("%sDTB property '%s'\n",
3447b4e1fbbSAlexei Fedorov 			"Unable to write ", DTB_PROP_HW_LOG_SIZE);
3457b4e1fbbSAlexei Fedorov 	} else {
3467b4e1fbbSAlexei Fedorov 		/*
3477b4e1fbbSAlexei Fedorov 		 * Ensure that the info written to the DTB is visible
3487b4e1fbbSAlexei Fedorov 		 * to other images.
3497b4e1fbbSAlexei Fedorov 		 */
3507b4e1fbbSAlexei Fedorov 		flush_dcache_range(config_base, fdt_totalsize(dtb));
3517b4e1fbbSAlexei Fedorov 	}
3527b4e1fbbSAlexei Fedorov 
3537b4e1fbbSAlexei Fedorov 	return err;
3547b4e1fbbSAlexei Fedorov }
3557b4e1fbbSAlexei Fedorov 
3567b4e1fbbSAlexei Fedorov /*
3577b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
3587b4e1fbbSAlexei Fedorov  * in the TOS_FW_CONFIG DTB.
3597b4e1fbbSAlexei Fedorov  *
3607b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
3617b4e1fbbSAlexei Fedorov  *
3627b4e1fbbSAlexei Fedorov  * Returns:
3637b4e1fbbSAlexei Fedorov  *	0 = success
3647b4e1fbbSAlexei Fedorov  *    < 0 = error
3657b4e1fbbSAlexei Fedorov  */
366efa65218SManish V Badarkhe int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size)
3677b4e1fbbSAlexei Fedorov {
368efa65218SManish V Badarkhe 	uintptr_t config_base;
369efa65218SManish V Badarkhe 	const bl_mem_params_node_t *cfg_mem_params;
3707b4e1fbbSAlexei Fedorov 	int err;
3717b4e1fbbSAlexei Fedorov 
3727b4e1fbbSAlexei Fedorov 	assert(log_addr != 0UL);
3737b4e1fbbSAlexei Fedorov 
374efa65218SManish V Badarkhe 	/* Get the config load address and size of TOS_FW_CONFIG */
375efa65218SManish V Badarkhe 	cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
376efa65218SManish V Badarkhe 	assert(cfg_mem_params != NULL);
377efa65218SManish V Badarkhe 
378efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
379efa65218SManish V Badarkhe 
380*10f6ccdcSYeoreum Yun #if TRANSFER_LIST
381*10f6ccdcSYeoreum Yun 	event_log_max_size = log_size;
382*10f6ccdcSYeoreum Yun #endif
383*10f6ccdcSYeoreum Yun 
3847b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
3857b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
3867b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
3877b4e1fbbSAlexei Fedorov 					0UL,
3887b4e1fbbSAlexei Fedorov #endif
3897b4e1fbbSAlexei Fedorov 					log_addr, log_size);
3907b4e1fbbSAlexei Fedorov 	if (err < 0) {
3917b4e1fbbSAlexei Fedorov 		ERROR("%sEvent Log data to TOS_FW_CONFIG\n",
3927b4e1fbbSAlexei Fedorov 					"Unable to write ");
3937b4e1fbbSAlexei Fedorov 	}
3947b4e1fbbSAlexei Fedorov 
3957b4e1fbbSAlexei Fedorov 	return err;
3967b4e1fbbSAlexei Fedorov }
3977b4e1fbbSAlexei Fedorov 
3987b4e1fbbSAlexei Fedorov /*
3997b4e1fbbSAlexei Fedorov  * This function writes the Event Log address and its size
4007b4e1fbbSAlexei Fedorov  * in the NT_FW_CONFIG DTB.
4017b4e1fbbSAlexei Fedorov  *
4027b4e1fbbSAlexei Fedorov  * This function is supposed to be called only by BL2.
4037b4e1fbbSAlexei Fedorov  *
4047b4e1fbbSAlexei Fedorov  * Returns:
4057b4e1fbbSAlexei Fedorov  *	0 = success
4067b4e1fbbSAlexei Fedorov  *    < 0 = error
4077b4e1fbbSAlexei Fedorov  */
408efa65218SManish V Badarkhe int arm_set_nt_fw_info(
4097b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
4107b4e1fbbSAlexei Fedorov 			uintptr_t log_addr,
4117b4e1fbbSAlexei Fedorov #endif
4127b4e1fbbSAlexei Fedorov 			size_t log_size, uintptr_t *ns_log_addr)
4137b4e1fbbSAlexei Fedorov {
414efa65218SManish V Badarkhe 	uintptr_t config_base;
4157b4e1fbbSAlexei Fedorov 	uintptr_t ns_addr;
4167b4e1fbbSAlexei Fedorov 	const bl_mem_params_node_t *cfg_mem_params;
4177b4e1fbbSAlexei Fedorov 	int err;
4187b4e1fbbSAlexei Fedorov 
4197b4e1fbbSAlexei Fedorov 	assert(ns_log_addr != NULL);
4207b4e1fbbSAlexei Fedorov 
4217b4e1fbbSAlexei Fedorov 	/* Get the config load address and size from NT_FW_CONFIG */
4227b4e1fbbSAlexei Fedorov 	cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
4237b4e1fbbSAlexei Fedorov 	assert(cfg_mem_params != NULL);
4247b4e1fbbSAlexei Fedorov 
425efa65218SManish V Badarkhe 	config_base = cfg_mem_params->image_info.image_base;
426efa65218SManish V Badarkhe 
4277b4e1fbbSAlexei Fedorov 	/* Calculate Event Log address in Non-secure memory */
4287b4e1fbbSAlexei Fedorov 	ns_addr = cfg_mem_params->image_info.image_base +
4297b4e1fbbSAlexei Fedorov 			cfg_mem_params->image_info.image_max_size;
4307b4e1fbbSAlexei Fedorov 
4317b4e1fbbSAlexei Fedorov 	/* Check for memory space */
4327b4e1fbbSAlexei Fedorov 	if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) {
4337b4e1fbbSAlexei Fedorov 		return -1;
4347b4e1fbbSAlexei Fedorov 	}
4357b4e1fbbSAlexei Fedorov 
4367b4e1fbbSAlexei Fedorov 	/* Write the Event Log address and its size in the DTB */
4377b4e1fbbSAlexei Fedorov 	err = arm_set_event_log_info(config_base,
4387b4e1fbbSAlexei Fedorov #ifdef SPD_opteed
4397b4e1fbbSAlexei Fedorov 					log_addr,
4407b4e1fbbSAlexei Fedorov #endif
4417b4e1fbbSAlexei Fedorov 					ns_addr, log_size);
4427b4e1fbbSAlexei Fedorov 
4437b4e1fbbSAlexei Fedorov 	/* Return Event Log address in Non-secure memory */
4447b4e1fbbSAlexei Fedorov 	*ns_log_addr = (err < 0) ? 0UL : ns_addr;
4457b4e1fbbSAlexei Fedorov 	return err;
4467b4e1fbbSAlexei Fedorov }
4470500f447SManish V Badarkhe 
4480500f447SManish V Badarkhe /*
4490500f447SManish V Badarkhe  * This function writes the Event Log address and its size
4500500f447SManish V Badarkhe  * in the TB_FW_CONFIG DTB.
4510500f447SManish V Badarkhe  *
4520500f447SManish V Badarkhe  * This function is supposed to be called only by BL1.
4530500f447SManish V Badarkhe  *
4540500f447SManish V Badarkhe  * Returns:
4550500f447SManish V Badarkhe  *     0 = success
4560500f447SManish V Badarkhe  *   < 0 = error
4570500f447SManish V Badarkhe  */
4581cf3e2f0SManish V Badarkhe int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size, size_t log_max_size)
4590500f447SManish V Badarkhe {
4600500f447SManish V Badarkhe 	/*
4610500f447SManish V Badarkhe 	 * Read tb_fw_config device tree for Event Log properties
4620500f447SManish V Badarkhe 	 * and write the Event Log address and its size in the DTB
4630500f447SManish V Badarkhe 	 */
4640500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
4650500f447SManish V Badarkhe 	uintptr_t tb_fw_cfg_dtb;
4660500f447SManish V Badarkhe 	int err;
4670500f447SManish V Badarkhe 
4680500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
4690500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
4700500f447SManish V Badarkhe 
4710500f447SManish V Badarkhe 	tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
4720500f447SManish V Badarkhe 
4731cf3e2f0SManish V Badarkhe 	event_log_max_size = log_max_size;
4741cf3e2f0SManish V Badarkhe 
4750500f447SManish V Badarkhe 	err = arm_set_event_log_info(tb_fw_cfg_dtb,
4760500f447SManish V Badarkhe #ifdef SPD_opteed
4770500f447SManish V Badarkhe 				     0UL,
4780500f447SManish V Badarkhe #endif
4790500f447SManish V Badarkhe 				     log_addr, log_size);
4800500f447SManish V Badarkhe 	return err;
4810500f447SManish V Badarkhe }
4820500f447SManish V Badarkhe 
4830500f447SManish V Badarkhe /*
4840500f447SManish V Badarkhe  * This function reads the Event Log address and its size
4850500f447SManish V Badarkhe  * properties present in TB_FW_CONFIG DTB.
4860500f447SManish V Badarkhe  *
4870500f447SManish V Badarkhe  * This function is supposed to be called only by BL2.
4880500f447SManish V Badarkhe  *
4890500f447SManish V Badarkhe  * Returns:
4900500f447SManish V Badarkhe  *     0 = success
4910500f447SManish V Badarkhe  *   < 0 = error
4920500f447SManish V Badarkhe  * Alongside returns Event Log address and its size.
4930500f447SManish V Badarkhe  */
4940500f447SManish V Badarkhe 
4951cf3e2f0SManish V Badarkhe int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
4961cf3e2f0SManish V Badarkhe 		       size_t *log_max_size)
4970500f447SManish V Badarkhe {
4980500f447SManish V Badarkhe 	/* As libfdt uses void *, we can't avoid this cast */
4990500f447SManish V Badarkhe 	const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
5000500f447SManish V Badarkhe 	int node, rc;
5010500f447SManish V Badarkhe 
5020500f447SManish V Badarkhe 	tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
5030500f447SManish V Badarkhe 	assert(tb_fw_config_info != NULL);
5040500f447SManish V Badarkhe 
5050500f447SManish V Badarkhe 	void *dtb = (void *)tb_fw_config_info->config_addr;
5060500f447SManish V Badarkhe 	const char *compatible = "arm,tpm_event_log";
5070500f447SManish V Badarkhe 
5080500f447SManish V Badarkhe 	/* Assert the node offset point to compatible property */
5090500f447SManish V Badarkhe 	node = fdt_node_offset_by_compatible(dtb, -1, compatible);
5100500f447SManish V Badarkhe 	if (node < 0) {
5110500f447SManish V Badarkhe 		WARN("The compatible property '%s'%s", compatible,
5120500f447SManish V Badarkhe 		     " not specified in TB_FW config.\n");
5130500f447SManish V Badarkhe 		return node;
5140500f447SManish V Badarkhe 	}
5150500f447SManish V Badarkhe 
5160500f447SManish V Badarkhe 	VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
5170500f447SManish V Badarkhe 
5180500f447SManish V Badarkhe 	rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr);
5190500f447SManish V Badarkhe 	if (rc != 0) {
5200500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_ADDR,
5210500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
5220500f447SManish V Badarkhe 		return rc;
5230500f447SManish V Badarkhe 	}
5240500f447SManish V Badarkhe 
5250500f447SManish V Badarkhe 	rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size);
5260500f447SManish V Badarkhe 	if (rc != 0) {
5270500f447SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
5280500f447SManish V Badarkhe 		      " not specified in TB_FW config.\n");
5291cf3e2f0SManish V Badarkhe 		return rc;
5301cf3e2f0SManish V Badarkhe 	}
5311cf3e2f0SManish V Badarkhe 
5321cf3e2f0SManish V Badarkhe 	rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_MAX_SIZE,
5331cf3e2f0SManish V Badarkhe 			     (uint32_t *)log_max_size);
5341cf3e2f0SManish V Badarkhe 	if (rc != 0) {
5351cf3e2f0SManish V Badarkhe 		ERROR("%s%s", DTB_PROP_HW_LOG_MAX_SIZE,
5361cf3e2f0SManish V Badarkhe 		      " not specified in TB_FW config.\n");
5371cf3e2f0SManish V Badarkhe 		return rc;
5381cf3e2f0SManish V Badarkhe 	} else {
5391cf3e2f0SManish V Badarkhe 		event_log_max_size = *log_max_size;
5400500f447SManish V Badarkhe 	}
5410500f447SManish V Badarkhe 
5420500f447SManish V Badarkhe 	return rc;
5430500f447SManish V Badarkhe }
5441f47a713STamas Ban #endif /* DICE_PROTECTION_ENVIRONMENT */
5450ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
546