1a5566f65SHarrison Mutai /*
2abdb953bSHarrison Mutai * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
3a5566f65SHarrison Mutai *
4a5566f65SHarrison Mutai * SPDX-License-Identifier: BSD-3-Clause
5a5566f65SHarrison Mutai */
6a5566f65SHarrison Mutai
7ada4e59dSHarrison Mutai #if CRYPTO_SUPPORT
8ada4e59dSHarrison Mutai #include <mbedtls/version.h>
9ada4e59dSHarrison Mutai #endif /* CRYPTO_SUPPORT */
10ada4e59dSHarrison Mutai
11a5566f65SHarrison Mutai #include <plat/arm/common/plat_arm.h>
12a5566f65SHarrison Mutai #include <platform_def.h>
13a5566f65SHarrison Mutai
14ada4e59dSHarrison Mutai #if CRYPTO_SUPPORT
15ada4e59dSHarrison Mutai #if defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31)
16ada4e59dSHarrison Mutai static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
17ada4e59dSHarrison Mutai
18ada4e59dSHarrison Mutai #define MBEDTLS_HEAP_ADDR heap
19ada4e59dSHarrison Mutai #define MBEDTLS_HEAP_SIZE sizeof(heap)
20ada4e59dSHarrison Mutai #else
21ada4e59dSHarrison Mutai static struct crypto_heap_info heap_info;
22ada4e59dSHarrison Mutai
23ada4e59dSHarrison Mutai #define MBEDTLS_HEAP_ADDR heap_info.addr
24ada4e59dSHarrison Mutai #define MBEDTLS_HEAP_SIZE heap_info.size
25ada4e59dSHarrison Mutai
26ada4e59dSHarrison Mutai struct transfer_list_entry *
arm_transfer_list_set_heap_info(struct transfer_list_header * tl)27ada4e59dSHarrison Mutai arm_transfer_list_set_heap_info(struct transfer_list_header *tl)
28ada4e59dSHarrison Mutai {
29ada4e59dSHarrison Mutai struct transfer_list_entry *te =
30ada4e59dSHarrison Mutai transfer_list_find(tl, TL_TAG_MBEDTLS_HEAP_INFO);
31ada4e59dSHarrison Mutai assert(te != NULL);
32ada4e59dSHarrison Mutai
33ada4e59dSHarrison Mutai heap_info = *(struct crypto_heap_info *)transfer_list_entry_data(te);
34ada4e59dSHarrison Mutai return te;
35ada4e59dSHarrison Mutai }
36ada4e59dSHarrison Mutai #endif /* defined(IMAGE_BL1) || RESET_TO_BL2 || defined(IMAGE_BL31) */
37ada4e59dSHarrison Mutai
arm_get_mbedtls_heap(void ** heap_addr,size_t * heap_size)38ada4e59dSHarrison Mutai int __init arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
39ada4e59dSHarrison Mutai {
40ada4e59dSHarrison Mutai assert(heap_addr != NULL);
41ada4e59dSHarrison Mutai assert(heap_size != NULL);
42ada4e59dSHarrison Mutai *heap_addr = MBEDTLS_HEAP_ADDR;
43ada4e59dSHarrison Mutai *heap_size = MBEDTLS_HEAP_SIZE;
44ada4e59dSHarrison Mutai
45ada4e59dSHarrison Mutai return 0;
46ada4e59dSHarrison Mutai }
47ada4e59dSHarrison Mutai #endif /* CRYPTO_SUPPORT */
48ada4e59dSHarrison Mutai
arm_transfer_list_dyn_cfg_init(struct transfer_list_header * tl)49d5705719SHarrison Mutai void arm_transfer_list_dyn_cfg_init(struct transfer_list_header *tl)
50a5566f65SHarrison Mutai {
51a5566f65SHarrison Mutai struct transfer_list_entry *te;
52a5566f65SHarrison Mutai bl_mem_params_node_t *next_param_node =
53a5566f65SHarrison Mutai get_bl_mem_params_node(HW_CONFIG_ID);
54a5566f65SHarrison Mutai assert(next_param_node != NULL);
55a5566f65SHarrison Mutai
56a5566f65SHarrison Mutai /*
57a5566f65SHarrison Mutai * The HW_CONFIG needs to be authenticated via the normal loading
58a5566f65SHarrison Mutai * mechanism. Pre-allocate a TE for the configuration and update the
59a5566f65SHarrison Mutai * load information so the configuration is loaded directly into the TE.
60a5566f65SHarrison Mutai */
61d5705719SHarrison Mutai te = transfer_list_add(tl, TL_TAG_FDT, PLAT_ARM_HW_CONFIG_SIZE, NULL);
62a5566f65SHarrison Mutai assert(te != NULL);
63a5566f65SHarrison Mutai
64a5566f65SHarrison Mutai next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
65a5566f65SHarrison Mutai next_param_node->image_info.image_max_size = PLAT_ARM_HW_CONFIG_SIZE;
66a5566f65SHarrison Mutai next_param_node->image_info.image_base =
67a5566f65SHarrison Mutai (uintptr_t)transfer_list_entry_data(te);
6800c353c4SYeoreum Yun
69*55fd56d7SYeoreum Yun #if defined(SPD_spmd) && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE)
7000c353c4SYeoreum Yun next_param_node = get_bl_mem_params_node(TOS_FW_CONFIG_ID);
71*55fd56d7SYeoreum Yun if (next_param_node == NULL) {
72*55fd56d7SYeoreum Yun return;
73*55fd56d7SYeoreum Yun }
7400c353c4SYeoreum Yun
75*55fd56d7SYeoreum Yun #if SPMC_AT_EL3
7600c353c4SYeoreum Yun te = transfer_list_add(tl, TL_TAG_DT_FFA_MANIFEST,
7700c353c4SYeoreum Yun PLAT_ARM_SPMC_SP_MANIFEST_SIZE, NULL);
78*55fd56d7SYeoreum Yun #else
79*55fd56d7SYeoreum Yun te = transfer_list_add(tl, TL_TAG_DT_SPMC_MANIFEST,
80*55fd56d7SYeoreum Yun PLAT_ARM_SPMC_SP_MANIFEST_SIZE, NULL);
81*55fd56d7SYeoreum Yun #endif
8200c353c4SYeoreum Yun assert(te != NULL);
8300c353c4SYeoreum Yun
8400c353c4SYeoreum Yun next_param_node->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
8500c353c4SYeoreum Yun next_param_node->image_info.image_max_size = PLAT_ARM_SPMC_SP_MANIFEST_SIZE;
8600c353c4SYeoreum Yun next_param_node->image_info.image_base =
8700c353c4SYeoreum Yun (uintptr_t)transfer_list_entry_data(te);
88*55fd56d7SYeoreum Yun #endif /* defined(SPD_spmd) && defined(PLAT_ARM_SPMC_SP_MANIFEST_SIZE) */
89a5566f65SHarrison Mutai }
90a5566f65SHarrison Mutai
arm_transfer_list_populate_ep_info(bl_mem_params_node_t * next_param_node,struct transfer_list_header * tl)91a5566f65SHarrison Mutai void arm_transfer_list_populate_ep_info(bl_mem_params_node_t *next_param_node,
92d5705719SHarrison Mutai struct transfer_list_header *tl)
93a5566f65SHarrison Mutai {
94a5566f65SHarrison Mutai uint32_t next_exe_img_id;
95abdb953bSHarrison Mutai entry_point_info_t *ep __unused;
96a5566f65SHarrison Mutai struct transfer_list_entry *te;
97a5566f65SHarrison Mutai assert(next_param_node != NULL);
98a5566f65SHarrison Mutai
99a5566f65SHarrison Mutai while ((next_exe_img_id = next_param_node->next_handoff_image_id) !=
100a5566f65SHarrison Mutai INVALID_IMAGE_ID) {
101a5566f65SHarrison Mutai next_param_node =
102a5566f65SHarrison Mutai &bl_mem_params_desc_ptr[get_bl_params_node_index(
103a5566f65SHarrison Mutai next_exe_img_id)];
104a5566f65SHarrison Mutai assert(next_param_node != NULL);
105a5566f65SHarrison Mutai
106abdb953bSHarrison Mutai te = transfer_list_add(tl, TL_TAG_EXEC_EP_INFO,
107a5566f65SHarrison Mutai sizeof(entry_point_info_t),
108a5566f65SHarrison Mutai &next_param_node->ep_info);
109a5566f65SHarrison Mutai assert(te != NULL);
110a5566f65SHarrison Mutai
111a5566f65SHarrison Mutai ep = transfer_list_entry_data(te);
112abdb953bSHarrison Mutai assert(ep != NULL);
113a5566f65SHarrison Mutai
114abdb953bSHarrison Mutai #if SPMC_AT_EL3
115abdb953bSHarrison Mutai if (next_exe_img_id == BL32_IMAGE_ID) {
116a5566f65SHarrison Mutai /*
117a5566f65SHarrison Mutai * Populate the BL32 image base, size and max limit in
118a5566f65SHarrison Mutai * the entry point information, since there is no
119a5566f65SHarrison Mutai * platform function to retrieve them in generic
120a5566f65SHarrison Mutai * code. We choose arg2, arg3 and arg4 since the generic
121a5566f65SHarrison Mutai * code uses arg1 for stashing the SP manifest size. The
122a5566f65SHarrison Mutai * SPMC setup uses these arguments to update SP manifest
123a5566f65SHarrison Mutai * with actual SP's base address and it size.
124a5566f65SHarrison Mutai */
125a5566f65SHarrison Mutai ep->args.arg2 = next_param_node->image_info.image_base;
126a5566f65SHarrison Mutai ep->args.arg3 = next_param_node->image_info.image_size;
127a5566f65SHarrison Mutai ep->args.arg4 =
128a5566f65SHarrison Mutai next_param_node->image_info.image_base +
129a5566f65SHarrison Mutai next_param_node->image_info.image_max_size;
130a5566f65SHarrison Mutai }
131abdb953bSHarrison Mutai #endif /* SPMC_AT_EL3 */
132a5566f65SHarrison Mutai
133a5566f65SHarrison Mutai next_exe_img_id = next_param_node->next_handoff_image_id;
134a5566f65SHarrison Mutai }
135a5566f65SHarrison Mutai
136d5705719SHarrison Mutai flush_dcache_range((uintptr_t)tl, tl->size);
137a5566f65SHarrison Mutai }
138