xref: /rk3399_ARM-atf/plat/arm/common/arm_dyn_cfg_helpers.c (revision 0ab496458b4cf55fa4116007506d8f38884bd31f)
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 
9cab0b5b0SSoby Mathew #include <libfdt.h>
1009d40e0eSAntonio Nino Diaz 
1109d40e0eSAntonio Nino Diaz #include <common/fdt_wrappers.h>
12bd9344f6SAntonio Nino Diaz #include <plat/arm/common/arm_dyn_cfg_helpers.h>
13bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
14cab0b5b0SSoby Mathew 
15ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
16ba597da7SJohn Tsichritzis #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
171d71ba14SSoby Mathew 
18*0ab49645SAlexei Fedorov #if MEASURED_BOOT
19*0ab49645SAlexei Fedorov #define DTB_PROP_BL2_HASH_DATA	"bl2_hash_data"
20*0ab49645SAlexei Fedorov 
21*0ab49645SAlexei Fedorov static int dtb_root = -1;
22*0ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
23*0ab49645SAlexei Fedorov 
24cab0b5b0SSoby Mathew /*******************************************************************************
25cab0b5b0SSoby Mathew  * Validate the tb_fw_config is a valid DTB file and returns the node offset
26cab0b5b0SSoby Mathew  * to "arm,tb_fw" property.
27cab0b5b0SSoby Mathew  * Arguments:
28cab0b5b0SSoby Mathew  *	void *dtb - pointer to the TB_FW_CONFIG in memory
29cab0b5b0SSoby Mathew  *	int *node - Returns the node offset to "arm,tb_fw" property if found.
30cab0b5b0SSoby Mathew  *
31cab0b5b0SSoby Mathew  * Returns 0 on success and -1 on error.
32cab0b5b0SSoby Mathew  ******************************************************************************/
33cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
34cab0b5b0SSoby Mathew {
35da5f2745SSoby Mathew 	assert(dtb != NULL);
36da5f2745SSoby Mathew 	assert(node != NULL);
37cab0b5b0SSoby Mathew 
38cab0b5b0SSoby Mathew 	/* Check if the pointer to DT is correct */
39cab0b5b0SSoby Mathew 	if (fdt_check_header(dtb) != 0) {
40cab0b5b0SSoby Mathew 		WARN("Invalid DTB file passed as TB_FW_CONFIG\n");
41cab0b5b0SSoby Mathew 		return -1;
42cab0b5b0SSoby Mathew 	}
43cab0b5b0SSoby Mathew 
44cab0b5b0SSoby Mathew 	/* Assert the node offset point to "arm,tb_fw" compatible property */
45cab0b5b0SSoby Mathew 	*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
46cab0b5b0SSoby Mathew 	if (*node < 0) {
47cab0b5b0SSoby Mathew 		WARN("The compatible property `arm,tb_fw` not found in the config\n");
48cab0b5b0SSoby Mathew 		return -1;
49cab0b5b0SSoby Mathew 	}
50cab0b5b0SSoby Mathew 
51cab0b5b0SSoby Mathew 	VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
52cab0b5b0SSoby Mathew 	return 0;
53cab0b5b0SSoby Mathew }
54ba597da7SJohn Tsichritzis 
55ba597da7SJohn Tsichritzis /*
56ba597da7SJohn Tsichritzis  * This function writes the Mbed TLS heap address and size in the DTB. When it
57ba597da7SJohn Tsichritzis  * is called, it is guaranteed that a DTB is available. However it is not
58ba597da7SJohn Tsichritzis  * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
59ba597da7SJohn Tsichritzis  * return error code from here and it's the responsibility of the caller to
60ba597da7SJohn Tsichritzis  * determine the action upon error.
61ba597da7SJohn Tsichritzis  *
62ba597da7SJohn Tsichritzis  * This function is supposed to be called only by BL1.
63ba597da7SJohn Tsichritzis  *
64ba597da7SJohn Tsichritzis  * Returns:
65ba597da7SJohn Tsichritzis  *	0 = success
66*0ab49645SAlexei Fedorov  *     -1 = error
67ba597da7SJohn Tsichritzis  */
68ba597da7SJohn Tsichritzis int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
69ba597da7SJohn Tsichritzis {
70*0ab49645SAlexei Fedorov #if !MEASURED_BOOT
71*0ab49645SAlexei Fedorov 	int dtb_root;
72*0ab49645SAlexei Fedorov #endif
73ba597da7SJohn Tsichritzis 	/*
74ba597da7SJohn Tsichritzis 	 * Verify that the DTB is valid, before attempting to write to it,
75ba597da7SJohn Tsichritzis 	 * and get the DTB root node.
76ba597da7SJohn Tsichritzis 	 */
77*0ab49645SAlexei Fedorov 	int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
78ba597da7SJohn Tsichritzis 	if (err < 0) {
797af2dd2eSJohn Tsichritzis 		ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n");
80ba597da7SJohn Tsichritzis 		return -1;
81ba597da7SJohn Tsichritzis 	}
82ba597da7SJohn Tsichritzis 
83ba597da7SJohn Tsichritzis 	/*
84ba597da7SJohn Tsichritzis 	 * Write the heap address and size in the DTB.
85ba597da7SJohn Tsichritzis 	 *
86ba597da7SJohn Tsichritzis 	 * NOTE: The variables heap_addr and heap_size are corrupted
87ba597da7SJohn Tsichritzis 	 * by the "fdtw_write_inplace_cells" function. After the
88ba597da7SJohn Tsichritzis 	 * function calls they must NOT be reused.
89ba597da7SJohn Tsichritzis 	 */
90ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
91ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
92ba597da7SJohn Tsichritzis 	if (err < 0) {
937af2dd2eSJohn Tsichritzis 		ERROR("Unable to write DTB property %s\n",
947af2dd2eSJohn Tsichritzis 			DTB_PROP_MBEDTLS_HEAP_ADDR);
95ba597da7SJohn Tsichritzis 		return -1;
96ba597da7SJohn Tsichritzis 	}
97ba597da7SJohn Tsichritzis 
98ba597da7SJohn Tsichritzis 	err = fdtw_write_inplace_cells(dtb, dtb_root,
99ba597da7SJohn Tsichritzis 		DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
100ba597da7SJohn Tsichritzis 	if (err < 0) {
1017af2dd2eSJohn Tsichritzis 		ERROR("Unable to write DTB property %s\n",
1027af2dd2eSJohn Tsichritzis 			DTB_PROP_MBEDTLS_HEAP_SIZE);
103ba597da7SJohn Tsichritzis 		return -1;
104ba597da7SJohn Tsichritzis 	}
105ba597da7SJohn Tsichritzis 
106ba597da7SJohn Tsichritzis 	return 0;
107ba597da7SJohn Tsichritzis }
108*0ab49645SAlexei Fedorov 
109*0ab49645SAlexei Fedorov #if MEASURED_BOOT
110*0ab49645SAlexei Fedorov /*
111*0ab49645SAlexei Fedorov  * This function writes the BL2 hash data in HW_FW_CONFIG DTB.
112*0ab49645SAlexei Fedorov  * When it is called, it is guaranteed that a DTB is available.
113*0ab49645SAlexei Fedorov  *
114*0ab49645SAlexei Fedorov  * This function is supposed to be called only by BL1.
115*0ab49645SAlexei Fedorov  *
116*0ab49645SAlexei Fedorov  * Returns:
117*0ab49645SAlexei Fedorov  *	0 = success
118*0ab49645SAlexei Fedorov  *    < 0 = error
119*0ab49645SAlexei Fedorov  */
120*0ab49645SAlexei Fedorov int arm_set_bl2_hash_info(void *dtb, void *data)
121*0ab49645SAlexei Fedorov {
122*0ab49645SAlexei Fedorov 	assert(dtb_root >= 0);
123*0ab49645SAlexei Fedorov 
124*0ab49645SAlexei Fedorov 	/*
125*0ab49645SAlexei Fedorov 	 * Write the BL2 hash data in the DTB.
126*0ab49645SAlexei Fedorov 	 */
127*0ab49645SAlexei Fedorov 	return fdtw_write_inplace_bytes(dtb, dtb_root, DTB_PROP_BL2_HASH_DATA,
128*0ab49645SAlexei Fedorov 					TCG_DIGEST_SIZE, data);
129*0ab49645SAlexei Fedorov }
130*0ab49645SAlexei Fedorov #endif /* MEASURED_BOOT */
131