blob: 5dc11151d01218c62b2e23c1221fcffe9aeff9dc [file] [log] [blame]
Soby Mathew96a1c6b2018-01-15 14:45:33 +00001/*
Manish V Badarkhe6e6df442023-03-20 14:58:06 +00002 * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
Soby Mathew96a1c6b2018-01-15 14:45:33 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
Claus Pedersen785e66c2022-09-12 22:42:58 +00009#include <common/debug.h>
Alexei Fedorovc7176172020-07-13 12:11:05 +010010#if MEASURED_BOOT
11#include <common/desc_image_load.h>
12#endif
13#include <common/fdt_wrappers.h>
14
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +010015#include <lib/fconf/fconf.h>
16#include <lib/fconf/fconf_dyn_cfg_getter.h>
Soby Mathew96a1c6b2018-01-15 14:45:33 +000017#include <libfdt.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000018
Antonio Nino Diazbd7b7402019-01-25 14:30:04 +000019#include <plat/arm/common/arm_dyn_cfg_helpers.h>
20#include <plat/arm/common/plat_arm.h>
Soby Mathew96a1c6b2018-01-15 14:45:33 +000021
John Tsichritzisc34341a2018-07-30 13:41:52 +010022#define DTB_PROP_MBEDTLS_HEAP_ADDR "mbedtls_heap_addr"
23#define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size"
Soby Mathewb6814842018-04-04 09:40:32 +010024
Alexei Fedorov25d7c882020-03-20 18:38:55 +000025#if MEASURED_BOOT
Alexei Fedorovc7176172020-07-13 12:11:05 +010026#ifdef SPD_opteed
27/*
28 * Currently OP-TEE does not support reading DTBs from Secure memory
29 * and this property should be removed when this feature is supported.
30 */
Manish V Badarkhe6e6df442023-03-20 14:58:06 +000031#define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr"
Manish V Badarkhe3ff0f792021-08-10 20:51:55 +010032#endif /* SPD_opteed */
Manish V Badarkhe6e6df442023-03-20 14:58:06 +000033#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
34#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
35#define DTB_PROP_HW_LOG_MAX_SIZE "tpm_event_log_max_size"
Alexei Fedorov25d7c882020-03-20 18:38:55 +000036#endif /* MEASURED_BOOT */
37
Manish V Badarkhe6e6df442023-03-20 14:58:06 +000038static size_t event_log_max_size __unused;
39
Soby Mathew96a1c6b2018-01-15 14:45:33 +000040/*******************************************************************************
41 * Validate the tb_fw_config is a valid DTB file and returns the node offset
42 * to "arm,tb_fw" property.
43 * Arguments:
44 * void *dtb - pointer to the TB_FW_CONFIG in memory
45 * int *node - Returns the node offset to "arm,tb_fw" property if found.
46 *
47 * Returns 0 on success and -1 on error.
48 ******************************************************************************/
49int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
50{
Soby Mathewcc364842018-02-21 01:16:39 +000051 assert(dtb != NULL);
52 assert(node != NULL);
Soby Mathew96a1c6b2018-01-15 14:45:33 +000053
54 /* Check if the pointer to DT is correct */
55 if (fdt_check_header(dtb) != 0) {
Alexei Fedorovc7176172020-07-13 12:11:05 +010056 WARN("Invalid DTB file passed as%s\n", " TB_FW_CONFIG");
Soby Mathew96a1c6b2018-01-15 14:45:33 +000057 return -1;
58 }
59
60 /* Assert the node offset point to "arm,tb_fw" compatible property */
61 *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
62 if (*node < 0) {
Alexei Fedorovc7176172020-07-13 12:11:05 +010063 WARN("The compatible property '%s' not%s", "arm,tb_fw",
64 " found in the config\n");
Soby Mathew96a1c6b2018-01-15 14:45:33 +000065 return -1;
66 }
67
Alexei Fedorovc7176172020-07-13 12:11:05 +010068 VERBOSE("Dyn cfg: '%s'%s", "arm,tb_fw", " found in the config\n");
Soby Mathew96a1c6b2018-01-15 14:45:33 +000069 return 0;
70}
John Tsichritzisc34341a2018-07-30 13:41:52 +010071
John Tsichritzisc34341a2018-07-30 13:41:52 +010072/*
John Tsichritzisc34341a2018-07-30 13:41:52 +010073 * This function writes the Mbed TLS heap address and size in the DTB. When it
74 * is called, it is guaranteed that a DTB is available. However it is not
75 * guaranteed that the shared Mbed TLS heap implementation is used. Thus we
76 * return error code from here and it's the responsibility of the caller to
77 * determine the action upon error.
78 *
79 * This function is supposed to be called only by BL1.
80 *
81 * Returns:
82 * 0 = success
Alexei Fedorov25d7c882020-03-20 18:38:55 +000083 * -1 = error
John Tsichritzisc34341a2018-07-30 13:41:52 +010084 */
85int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size)
86{
Alexei Fedorov25d7c882020-03-20 18:38:55 +000087 int dtb_root;
Manish V Badarkhe3ff0f792021-08-10 20:51:55 +010088
John Tsichritzisc34341a2018-07-30 13:41:52 +010089 /*
90 * Verify that the DTB is valid, before attempting to write to it,
91 * and get the DTB root node.
92 */
Alexei Fedorov25d7c882020-03-20 18:38:55 +000093 int err = arm_dyn_tb_fw_cfg_init(dtb, &dtb_root);
John Tsichritzisc34341a2018-07-30 13:41:52 +010094 if (err < 0) {
Alexei Fedorovc7176172020-07-13 12:11:05 +010095 ERROR("Invalid%s loaded. Unable to get root node\n",
96 " TB_FW_CONFIG");
John Tsichritzisc34341a2018-07-30 13:41:52 +010097 return -1;
98 }
99
100 /*
101 * Write the heap address and size in the DTB.
102 *
103 * NOTE: The variables heap_addr and heap_size are corrupted
104 * by the "fdtw_write_inplace_cells" function. After the
105 * function calls they must NOT be reused.
106 */
107 err = fdtw_write_inplace_cells(dtb, dtb_root,
108 DTB_PROP_MBEDTLS_HEAP_ADDR, 2, &heap_addr);
109 if (err < 0) {
Alexei Fedorovc7176172020-07-13 12:11:05 +0100110 ERROR("%sDTB property '%s'\n",
111 "Unable to write ", DTB_PROP_MBEDTLS_HEAP_ADDR);
John Tsichritzisc34341a2018-07-30 13:41:52 +0100112 return -1;
113 }
114
115 err = fdtw_write_inplace_cells(dtb, dtb_root,
116 DTB_PROP_MBEDTLS_HEAP_SIZE, 1, &heap_size);
117 if (err < 0) {
Alexei Fedorovc7176172020-07-13 12:11:05 +0100118 ERROR("%sDTB property '%s'\n",
119 "Unable to write ", DTB_PROP_MBEDTLS_HEAP_SIZE);
John Tsichritzisc34341a2018-07-30 13:41:52 +0100120 return -1;
121 }
122
123 return 0;
124}
Alexei Fedorov25d7c882020-03-20 18:38:55 +0000125
126#if MEASURED_BOOT
127/*
Alexei Fedorovc7176172020-07-13 12:11:05 +0100128 * Write the Event Log address and its size in the DTB.
129 *
Alexei Fedorovc7176172020-07-13 12:11:05 +0100130 * Returns:
131 * 0 = success
132 * < 0 = error
133 */
134static int arm_set_event_log_info(uintptr_t config_base,
135#ifdef SPD_opteed
136 uintptr_t sm_log_addr,
137#endif
138 uintptr_t log_addr, size_t log_size)
139{
140 /* As libfdt uses void *, we can't avoid this cast */
141 void *dtb = (void *)config_base;
142 const char *compatible = "arm,tpm_event_log";
143 int err, node;
144
145 /*
146 * Verify that the DTB is valid, before attempting to write to it,
147 * and get the DTB root node.
148 */
149
150 /* Check if the pointer to DT is correct */
151 err = fdt_check_header(dtb);
152 if (err < 0) {
153 WARN("Invalid DTB file passed\n");
154 return err;
155 }
156
157 /* Assert the node offset point to compatible property */
158 node = fdt_node_offset_by_compatible(dtb, -1, compatible);
159 if (node < 0) {
160 WARN("The compatible property '%s' not%s", compatible,
161 " found in the config\n");
162 return node;
163 }
164
165 VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
166
167#ifdef SPD_opteed
168 if (sm_log_addr != 0UL) {
169 err = fdtw_write_inplace_cells(dtb, node,
170 DTB_PROP_HW_SM_LOG_ADDR, 2, &sm_log_addr);
171 if (err < 0) {
172 ERROR("%sDTB property '%s'\n",
173 "Unable to write ", DTB_PROP_HW_SM_LOG_ADDR);
174 return err;
175 }
176 }
177#endif
178 err = fdtw_write_inplace_cells(dtb, node,
179 DTB_PROP_HW_LOG_ADDR, 2, &log_addr);
180 if (err < 0) {
181 ERROR("%sDTB property '%s'\n",
182 "Unable to write ", DTB_PROP_HW_LOG_ADDR);
183 return err;
184 }
185
Manish V Badarkhe6e6df442023-03-20 14:58:06 +0000186 assert(event_log_max_size != 0U);
187 err = fdtw_write_inplace_cells(dtb, node,
188 DTB_PROP_HW_LOG_MAX_SIZE, 1,
189 &event_log_max_size);
190 if (err < 0) {
191 ERROR("%sDTB property '%s'\n",
192 "Unable to write ", DTB_PROP_HW_LOG_MAX_SIZE);
193 return err;
194 }
195
Alexei Fedorovc7176172020-07-13 12:11:05 +0100196 err = fdtw_write_inplace_cells(dtb, node,
197 DTB_PROP_HW_LOG_SIZE, 1, &log_size);
198 if (err < 0) {
199 ERROR("%sDTB property '%s'\n",
200 "Unable to write ", DTB_PROP_HW_LOG_SIZE);
201 } else {
202 /*
203 * Ensure that the info written to the DTB is visible
204 * to other images.
205 */
206 flush_dcache_range(config_base, fdt_totalsize(dtb));
207 }
208
209 return err;
210}
211
212/*
213 * This function writes the Event Log address and its size
214 * in the TOS_FW_CONFIG DTB.
215 *
216 * This function is supposed to be called only by BL2.
217 *
218 * Returns:
219 * 0 = success
220 * < 0 = error
221 */
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100222int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size)
Alexei Fedorovc7176172020-07-13 12:11:05 +0100223{
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100224 uintptr_t config_base;
225 const bl_mem_params_node_t *cfg_mem_params;
Alexei Fedorovc7176172020-07-13 12:11:05 +0100226 int err;
227
Alexei Fedorovc7176172020-07-13 12:11:05 +0100228 assert(log_addr != 0UL);
229
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100230 /* Get the config load address and size of TOS_FW_CONFIG */
231 cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
232 assert(cfg_mem_params != NULL);
233
234 config_base = cfg_mem_params->image_info.image_base;
235
Alexei Fedorovc7176172020-07-13 12:11:05 +0100236 /* Write the Event Log address and its size in the DTB */
237 err = arm_set_event_log_info(config_base,
238#ifdef SPD_opteed
239 0UL,
240#endif
241 log_addr, log_size);
242 if (err < 0) {
243 ERROR("%sEvent Log data to TOS_FW_CONFIG\n",
244 "Unable to write ");
245 }
246
247 return err;
248}
249
250/*
251 * This function writes the Event Log address and its size
252 * in the NT_FW_CONFIG DTB.
253 *
254 * This function is supposed to be called only by BL2.
255 *
256 * Returns:
257 * 0 = success
258 * < 0 = error
259 */
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100260int arm_set_nt_fw_info(
Alexei Fedorovc7176172020-07-13 12:11:05 +0100261#ifdef SPD_opteed
262 uintptr_t log_addr,
263#endif
264 size_t log_size, uintptr_t *ns_log_addr)
265{
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100266 uintptr_t config_base;
Alexei Fedorovc7176172020-07-13 12:11:05 +0100267 uintptr_t ns_addr;
268 const bl_mem_params_node_t *cfg_mem_params;
269 int err;
270
Alexei Fedorovc7176172020-07-13 12:11:05 +0100271 assert(ns_log_addr != NULL);
272
273 /* Get the config load address and size from NT_FW_CONFIG */
274 cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
275 assert(cfg_mem_params != NULL);
276
Manish V Badarkhe7ca9d652021-09-14 22:41:46 +0100277 config_base = cfg_mem_params->image_info.image_base;
278
Alexei Fedorovc7176172020-07-13 12:11:05 +0100279 /* Calculate Event Log address in Non-secure memory */
280 ns_addr = cfg_mem_params->image_info.image_base +
281 cfg_mem_params->image_info.image_max_size;
282
283 /* Check for memory space */
284 if ((uint64_t)(ns_addr + log_size) > ARM_NS_DRAM1_END) {
285 return -1;
286 }
287
288 /* Write the Event Log address and its size in the DTB */
289 err = arm_set_event_log_info(config_base,
290#ifdef SPD_opteed
291 log_addr,
292#endif
293 ns_addr, log_size);
294
295 /* Return Event Log address in Non-secure memory */
296 *ns_log_addr = (err < 0) ? 0UL : ns_addr;
297 return err;
298}
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +0100299
300/*
301 * This function writes the Event Log address and its size
302 * in the TB_FW_CONFIG DTB.
303 *
304 * This function is supposed to be called only by BL1.
305 *
306 * Returns:
307 * 0 = success
308 * < 0 = error
309 */
Manish V Badarkhe6e6df442023-03-20 14:58:06 +0000310int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size, size_t log_max_size)
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +0100311{
312 /*
313 * Read tb_fw_config device tree for Event Log properties
314 * and write the Event Log address and its size in the DTB
315 */
316 const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
317 uintptr_t tb_fw_cfg_dtb;
318 int err;
319
320 tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
321 assert(tb_fw_config_info != NULL);
322
323 tb_fw_cfg_dtb = tb_fw_config_info->config_addr;
324
Manish V Badarkhe6e6df442023-03-20 14:58:06 +0000325 event_log_max_size = log_max_size;
326
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +0100327 err = arm_set_event_log_info(tb_fw_cfg_dtb,
328#ifdef SPD_opteed
329 0UL,
330#endif
331 log_addr, log_size);
332 return err;
333}
334
335/*
336 * This function reads the Event Log address and its size
337 * properties present in TB_FW_CONFIG DTB.
338 *
339 * This function is supposed to be called only by BL2.
340 *
341 * Returns:
342 * 0 = success
343 * < 0 = error
344 * Alongside returns Event Log address and its size.
345 */
346
Manish V Badarkhe6e6df442023-03-20 14:58:06 +0000347int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size,
348 size_t *log_max_size)
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +0100349{
350 /* As libfdt uses void *, we can't avoid this cast */
351 const struct dyn_cfg_dtb_info_t *tb_fw_config_info;
352 int node, rc;
353
354 tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID);
355 assert(tb_fw_config_info != NULL);
356
357 void *dtb = (void *)tb_fw_config_info->config_addr;
358 const char *compatible = "arm,tpm_event_log";
359
360 /* Assert the node offset point to compatible property */
361 node = fdt_node_offset_by_compatible(dtb, -1, compatible);
362 if (node < 0) {
363 WARN("The compatible property '%s'%s", compatible,
364 " not specified in TB_FW config.\n");
365 return node;
366 }
367
368 VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n");
369
370 rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr);
371 if (rc != 0) {
372 ERROR("%s%s", DTB_PROP_HW_LOG_ADDR,
373 " not specified in TB_FW config.\n");
374 return rc;
375 }
376
377 rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size);
378 if (rc != 0) {
379 ERROR("%s%s", DTB_PROP_HW_LOG_SIZE,
380 " not specified in TB_FW config.\n");
Manish V Badarkhe6e6df442023-03-20 14:58:06 +0000381 return rc;
382 }
383
384 rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_MAX_SIZE,
385 (uint32_t *)log_max_size);
386 if (rc != 0) {
387 ERROR("%s%s", DTB_PROP_HW_LOG_MAX_SIZE,
388 " not specified in TB_FW config.\n");
389 return rc;
390 } else {
391 event_log_max_size = *log_max_size;
Manish V Badarkhe4edf4bd2021-08-11 10:45:03 +0100392 }
393
394 return rc;
395}
Alexei Fedorov25d7c882020-03-20 18:38:55 +0000396#endif /* MEASURED_BOOT */