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 ******************************************************************************/ 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 */ 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 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 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