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