1 /*
2 * Copyright 2019-2021, 2023 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 /* Multicore packed image loader implementation */
10
11 #include <string.h>
12
13 #include "fsl_common.h"
14 #include "fsl_mpi_loader.h"
15
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19 /*****************************************************
20 * TZM preset size definition for different devices. *
21 *****************************************************/
22 #define MPI_TZM_PRESET_SIZE_RT5XX (1140U)
23 #define MPI_TZM_PRESET_SIZE_RT6XX (1052U)
24
25 #define MPI_ASSERT(x) \
26 do \
27 { \
28 if (!(x)) \
29 { \
30 while (true) \
31 { \
32 } \
33 } \
34 } while (false)
35
36 #if defined(MIMXRT595S_cm33_SERIES) || defined(MIMXRT555S_SERIES) || defined(MIMXRT533S_SERIES)
37 #define MPI_TZM_PRESET_SIZE MPI_TZM_PRESET_SIZE_RT5XX
38 #define MPI_ADDRESS_MASK (0xEFFFFFFFU) /* Bit28 is secure address indicator */
39 #define MPI_MEMCPY (void)memcpy
40 #define MPI_MEMCLR (void)memset
41
42 #elif defined(MIMXRT685S_cm33_SERIES) || defined(MIMXRT633S_SERIES)
43 #define MPI_TZM_PRESET_SIZE MPI_TZM_PRESET_SIZE_RT6XX
44 #define MPI_ADDRESS_MASK (0xEFFFFFFFU) /* Bit28 is secure address indicator */
45 #define MPI_MEMCPY MPI_WordCopy
46 #define MPI_MEMCLR MPI_WordSet
47
48 #else
49 #error "Device not supported by Multicore Packed Image Loader!"
50 #endif
51
52 /*********************************
53 * Image type fields definition. *
54 *********************************/
55 #define MPI_TYPE_IMAGE_BASE_SHIFT (0U)
56 #define MPI_TYPE_IMAGE_BASE_MASK (0xFFU << (MPI_TYPE_IMAGE_BASE_SHIFT))
57 #define MPI_TYPE_IMAGE_BASE_PLAIN_SIGNED (1U << (MPI_TYPE_IMAGE_BASE_SHIFT))
58 #define MPI_TYPE_IMAGE_BASE_PLAIN_UNSIGNED (2U << (MPI_TYPE_IMAGE_BASE_SHIFT))
59 #define MPI_TYPE_IMAGE_BASE_ENCRYPTED_SIGNED (3U << (MPI_TYPE_IMAGE_BASE_SHIFT))
60 #define MPI_TYPE_IMAGE_BASE_XIP_PLAIN_SIGNED (4U << (MPI_TYPE_IMAGE_BASE_SHIFT))
61 #define MPI_TYPE_IMAGE_BASE_XIP_PLAIN_UNSIGNED (5U << (MPI_TYPE_IMAGE_BASE_SHIFT))
62
63 #define MPI_TYPE_MULTICORE_PACKED_SHIFT (11U)
64 #define MPI_TYPE_MULTICORE_PACKED_MASK (1UL << (MPI_TYPE_MULTICORE_PACKED_SHIFT))
65
66 #define MPI_TYPE_TZM_SHIFT (13U)
67 #define MPI_TYPE_TZM_MASK (3UL << (MPI_TYPE_TZM_SHIFT))
68 /* Trustzone enabled secure image. */
69 #define MPI_TYPE_TZM_SECURE (0UL << MPI_TYPE_TZM_SHIFT)
70 /* Trustzone enabled secure image with preset values. */
71 #define MPI_TYPE_TZM_SECURE_PRESET (1UL << MPI_TYPE_TZM_SHIFT)
72 /* Trustzone disabled non-secure image entry. */
73 #define MPI_TYPE_TZM_NONSECURE (2UL << MPI_TYPE_TZM_SHIFT)
74
75 /********************************
76 * Relocation table definition. *
77 ********************************/
78 #define MPI_RELOC_MARKER (0x4C54424CU)
79 #define MPI_RELOC_FLAG_LTI_LOAD (1U << 0)
80 #define MPI_RELOC_FLAG_LTI_INIT (1U << 1)
81 #define MPI_RELOC_FLAG_LTI_OVERLAP (1U << 2)
82
83 typedef struct
84 {
85 uint32_t srcAddr;
86 uint32_t destAddr;
87 uint32_t segmentSize;
88 uint32_t flags;
89 } mpi_reloc_entry_t;
90
91 typedef struct
92 {
93 uint32_t marker; /* always set to 0x4C54424C */
94 uint32_t version;
95 uint32_t numberOfEntries;
96 uint32_t entriesOff;
97 } mpi_reloc_table_t;
98
99 /*******************************************************************************
100 * Prototypes
101 ******************************************************************************/
102
103 /*******************************************************************************
104 * Variables
105 ******************************************************************************/
106
107 /*******************************************************************************
108 * Code
109 ******************************************************************************/
110 #if defined(MIMXRT685S_cm33_SERIES) || defined(MIMXRT633S_SERIES)
MPI_WordCopy(void * dest,void * src,uint32_t size)111 static void MPI_WordCopy(void *dest, void *src, uint32_t size)
112 {
113 uint32_t *s, *d;
114
115 MPI_ASSERT(src != NULL && (((uint32_t)(uint32_t *)src & 3U) == 0U));
116 MPI_ASSERT(dest != NULL && (((uint32_t)(uint32_t *)dest & 3U) == 0U));
117 MPI_ASSERT((size & 3U) == 0U);
118
119 s = (uint32_t *)src;
120 d = (uint32_t *)dest;
121
122 while (size > 0U)
123 {
124 *d++ = *s++;
125 size -= 4U;
126 }
127 }
128
MPI_WordSet(void * ptr,uint32_t value,uint32_t size)129 static void MPI_WordSet(void *ptr, uint32_t value, uint32_t size)
130 {
131 uint32_t *p;
132
133 MPI_ASSERT(ptr != NULL && (((uint32_t)(uint32_t *)ptr & 3U) == 0U));
134 MPI_ASSERT((size & 3U) == 0U);
135
136 p = (uint32_t *)ptr;
137
138 while (size > 0U)
139 {
140 *p++ = value;
141 size -= 4U;
142 }
143 }
144 #endif
145
MPI_Relocate(uint32_t * vect,mpi_reloc_entry_t * entry)146 static void MPI_Relocate(uint32_t *vect, mpi_reloc_entry_t *entry)
147 {
148 uint32_t srcAddr;
149
150 MPI_ASSERT(entry != NULL);
151
152 srcAddr = ((uint32_t)vect) + entry->srcAddr;
153
154 switch (entry->flags)
155 {
156 case MPI_RELOC_FLAG_LTI_LOAD:
157 if ((srcAddr & MPI_ADDRESS_MASK) != (entry->destAddr & MPI_ADDRESS_MASK))
158 {
159 MPI_MEMCPY((void *)(uint32_t *)entry->destAddr, (void *)(uint32_t *)srcAddr, entry->segmentSize);
160 }
161 break;
162 case MPI_RELOC_FLAG_LTI_INIT:
163 MPI_MEMCLR((void *)(uint32_t *)entry->destAddr, 0, entry->segmentSize);
164 break;
165 case MPI_RELOC_FLAG_LTI_OVERLAP:
166 /* Do nothing */
167 default:
168 /* Do nothing */
169 break;
170 }
171 }
172
MPI_HandleRelocTable(uint32_t * vect)173 static void MPI_HandleRelocTable(uint32_t *vect)
174 {
175 uint32_t i;
176 uint32_t imageLen;
177 uint32_t imageType;
178 uint32_t imageBase;
179 uint32_t relocTabEnd;
180 mpi_reloc_table_t *pRelocTab;
181 mpi_reloc_entry_t *pRelocEntry;
182
183 MPI_ASSERT(vect != NULL);
184
185 imageLen = vect[8];
186 imageType = vect[9];
187
188 if ((imageType & MPI_TYPE_MULTICORE_PACKED_MASK) != 0U)
189 {
190 /* Need to load other images. */
191 imageBase = imageType & MPI_TYPE_IMAGE_BASE_MASK;
192 if (imageBase == MPI_TYPE_IMAGE_BASE_PLAIN_SIGNED || imageBase == MPI_TYPE_IMAGE_BASE_ENCRYPTED_SIGNED ||
193 imageBase == MPI_TYPE_IMAGE_BASE_XIP_PLAIN_SIGNED)
194 {
195 /* Offset 0x28 is certificate header offset. */
196 relocTabEnd = vect[10];
197 }
198 else
199 {
200 /* Offset 0x28 is CRC. */
201 relocTabEnd = imageLen;
202 if ((imageType & MPI_TYPE_TZM_MASK) == MPI_TYPE_TZM_SECURE_PRESET)
203 {
204 /* Has TZM preset data, need to minus the size for relocation table pointer. */
205 relocTabEnd -= MPI_TZM_PRESET_SIZE;
206 }
207 }
208 pRelocTab = (mpi_reloc_table_t *)(((uint32_t)vect) + relocTabEnd) - 1;
209 MPI_ASSERT(pRelocTab->marker == MPI_RELOC_MARKER);
210
211 pRelocEntry = (mpi_reloc_entry_t *)(((uint32_t)vect) + pRelocTab->entriesOff);
212 for (i = 0; i < pRelocTab->numberOfEntries; i++)
213 {
214 MPI_Relocate(vect, pRelocEntry + i);
215 }
216 }
217 }
218
219 /* Must finish loading before application .data, .bss get initialized. */
MPI_LoadMultiImages(void)220 void MPI_LoadMultiImages(void)
221 {
222 extern uint32_t __VECTOR_TABLE[];
223
224 MPI_HandleRelocTable(__VECTOR_TABLE);
225 }
226