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