blob: ac6c99d2b9bfe0558380784f958ee7f5e4295573 [file] [log] [blame]
Soby Mathewcab0b5b2018-01-15 14:45:33 +00001/*
Zelaleme6937282020-02-03 14:56:42 -06002 * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
Soby Mathewcab0b5b2018-01-15 14:45:33 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +00008
Soby Mathewcab0b5b2018-01-15 14:45:33 +00009#include <libfdt.h>
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000010
Antonio Nino Diaz09d40e02018-12-14 00:18:21 +000011#include <common/fdt_wrappers.h>
Antonio Nino Diazbd9344f2019-01-25 14:30:04 +000012#include <plat/arm/common/arm_dyn_cfg_helpers.h>
13#include <plat/arm/common/plat_arm.h>
Soby Mathewcab0b5b2018-01-15 14:45:33 +000014
John Tsichritzisba597da2018-07-30 13:41:52 +010015#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
16#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
Soby Mathew1d71ba12018-04-04 09:40:32 +010017
Soby Mathewcab0b5b2018-01-15 14:45:33 +000018/*******************************************************************************
Soby Mathew6e79f9f2018-03-26 15:16:46 +010019 * Helper to read the `disable_auth` property in config DTB. This function
20 * expects the following properties to be present in the config DTB.
21 * name : disable_auth size : 1 cell
22 *
23 * Arguments:
24 * void *dtb - pointer to the TB_FW_CONFIG in memory
25 * int node - The node offset to appropriate node in the
26 * DTB.
27 * uint64_t *disable_auth - The value of `disable_auth` property on
28 * successful read. Must be 0 or 1.
29 *
30 * Returns 0 on success and -1 on error.
31 ******************************************************************************/
32int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth)
33{
34 int err;
35
36 assert(dtb != NULL);
37 assert(disable_auth != NULL);
38
39 /* Check if the pointer to DT is correct */
40 assert(fdt_check_header(dtb) == 0);
41
42 /* Assert the node offset point to "arm,tb_fw" compatible property */
43 assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
44
45 /* Locate the disable_auth cell and read the value */
46 err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth);
47 if (err < 0) {
48 WARN("Read cell failed for `disable_auth`\n");
49 return -1;
50 }
51
52 /* Check if the value is boolean */
Soby Mathew1d71ba12018-04-04 09:40:32 +010053 if ((*disable_auth != 0U) && (*disable_auth != 1U)) {
Soby Mathew6e79f9f2018-03-26 15:16:46 +010054 WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth);
55 return -1;
56 }
57
58 VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n",
59 *disable_auth);
60 return 0;
61}
62
63/*******************************************************************************
Soby Mathewcab0b5b2018-01-15 14:45:33 +000064 * Validate the tb_fw_config is a valid DTB file and returns the node offset
65 * to "arm,tb_fw" property.
66 * Arguments:
67 * void *dtb - pointer to the TB_FW_CONFIG in memory
68 * int *node - Returns the node offset to "arm,tb_fw" property if found.
69 *
70 * Returns 0 on success and -1 on error.
71 ******************************************************************************/
72int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
73{
Soby Mathewda5f2742018-02-21 01:16:39 +000074 assert(dtb != NULL);
75 assert(node != NULL);
Soby Mathewcab0b5b2018-01-15 14:45:33 +000076
77 /* Check if the pointer to DT is correct */
78 if (fdt_check_header(dtb) != 0) {
79 WARN("Invalid DTB file passed as TB_FW_CONFIG\n");
80 return -1;
81 }
82
83 /* Assert the node offset point to "arm,tb_fw" compatible property */
84 *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
85 if (*node < 0) {
86 WARN("The compatible property `arm,tb_fw` not found in the config\n");
87 return -1;
88 }
89
90 VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
91 return 0;
92}
John Tsichritzisba597da2018-07-30 13:41:52 +010093
John Tsichritzisba597da2018-07-30 13:41:52 +010094/*
95 * Reads and returns the Mbed TLS shared heap information from the DTB.
96 * This function is supposed to be called *only* when a DTB is present.
97 * This function is supposed to be called only by BL2.
98 *
99 * Returns:
100 * 0 = success
101 * -1 = error. In this case the values of heap_addr, heap_size should be
102 * considered as garbage by the caller.
103 */
104int arm_get_dtb_mbedtls_heap_info(void *dtb, void **heap_addr,
105 size_t *heap_size)
106{
107 int err, dtb_root;
108
109 /* Verify the DTB is valid and get the root node */
110 err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
111 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100112 ERROR("Invalid TB_FW_CONFIG. Cannot retrieve Mbed TLS heap information from DTB\n");
John Tsichritzisba597da2018-07-30 13:41:52 +0100113 return -1;
114 }
115
116 /* Retrieve the Mbed TLS heap details from the DTB */
117 err = fdtw_read_cells(dtb, dtb_root,
118 DTB_PROP_MBEDTLS_HEAP_ADDR, 2, heap_addr);
119 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100120 ERROR("Error while reading %s from DTB\n",
John Tsichritzisba597da2018-07-30 13:41:52 +0100121 DTB_PROP_MBEDTLS_HEAP_ADDR);
122 return -1;
123 }
124 err = fdtw_read_cells(dtb, dtb_root,
125 DTB_PROP_MBEDTLS_HEAP_SIZE, 1, heap_size);
126 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100127 ERROR("Error while reading %s from DTB\n",
John Tsichritzisba597da2018-07-30 13:41:52 +0100128 DTB_PROP_MBEDTLS_HEAP_SIZE);
129 return -1;
130 }
131 return 0;
132}
133
134
135/*
136 * This function writes the Mbed TLS heap address and size in the DTB. When it
137 * is called, it is guaranteed that a DTB is available. However it is not
138 * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
139 * return error code from here and it's the responsibility of the caller to
140 * determine the action upon error.
141 *
142 * This function is supposed to be called only by BL1.
143 *
144 * Returns:
145 * 0 = success
146 * 1 = error
147 */
148int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
149{
150 int err, dtb_root;
151
152 /*
153 * Verify that the DTB is valid, before attempting to write to it,
154 * and get the DTB root node.
155 */
156 err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
157 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100158 ERROR("Invalid TB_FW_CONFIG loaded. Unable to get root node\n");
John Tsichritzisba597da2018-07-30 13:41:52 +0100159 return -1;
160 }
161
162 /*
163 * Write the heap address and size in the DTB.
164 *
165 * NOTE: The variables heap_addr and heap_size are corrupted
166 * by the "fdtw_write_inplace_cells" function. After the
167 * function calls they must NOT be reused.
168 */
169 err = fdtw_write_inplace_cells(dtb, dtb_root,
170 DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
171 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100172 ERROR("Unable to write DTB property %s\n",
173 DTB_PROP_MBEDTLS_HEAP_ADDR);
John Tsichritzisba597da2018-07-30 13:41:52 +0100174 return -1;
175 }
176
177 err = fdtw_write_inplace_cells(dtb, dtb_root,
178 DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
179 if (err < 0) {
John Tsichritzis7af2dd22018-09-07 10:38:01 +0100180 ERROR("Unable to write DTB property %s\n",
181 DTB_PROP_MBEDTLS_HEAP_SIZE);
John Tsichritzisba597da2018-07-30 13:41:52 +0100182 return -1;
183 }
184
185 return 0;
186}