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 ******************************************************************************/
arm_dyn_tb_fw_cfg_init(void * dtb,int * node)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 */
arm_set_dtb_mbedtls_heap_info(void * dtb,void * heap_addr,size_t heap_size)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
arm_set_dpe_context_handle(uintptr_t config_base,int * ctx_handle)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 */
arm_set_nt_fw_info(int * ctx_handle)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 */
arm_set_tb_fw_info(int * ctx_handle)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
arm_get_tb_fw_info(int * ctx_handle)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 */
arm_set_event_log_info(uintptr_t config_base,uintptr_t sm_log_addr,uintptr_t log_addr,size_t log_size)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 */
arm_set_tos_fw_info(uintptr_t log_addr,size_t log_size)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 */
arm_set_nt_fw_info(uintptr_t log_addr,size_t log_size,uintptr_t * ns_log_addr)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 */
arm_set_tb_fw_info(uintptr_t log_addr,size_t log_size,size_t log_max_size)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
arm_get_tb_fw_info(uint64_t * log_addr,size_t * log_size,size_t * log_max_size)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