-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstm32_boot_lrun.c
275 lines (244 loc) · 7.75 KB
/
stm32_boot_lrun.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/**
******************************************************************************
* @file stm32_boot_lrun.c
* @author MCD Application Team
* @brief this file manages the boot in the mode load and run.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32_boot_lrun.h"
/** @defgroup BOOT
* @{
*/
/** @defgroup BOOT_LRUN
* @{
*/
/* Private typedefs ----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* offset of the vector table from the start of the image. Should be set in extmem_conf.h if needed */
#ifndef EXTMEM_HEADER_OFFSET
#define EXTMEM_HEADER_OFFSET 0
#endif
#if defined(EXTMEM_LRUN_TS_ENABLE_NS) && (!defined(EXTMEM_LRUN_DESTINATION_ADDRESS_NS) \
|| !defined(EXTMEM_LRUN_SOURCE_ADDRESS_NS))
#error "ExtMem user configuration incorrect : undefined parameters for Non-Secure image loading"
#endif
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
BOOTStatus_TypeDef MapMemory(void);
BOOTStatus_TypeDef CopyApplication(void);
BOOTStatus_TypeDef JumpToApplication(void);
BOOTStatus_TypeDef GetBaseAddress(uint32_t MemIndex, uint32_t *BaseAddress);
/**
* @addtogroup BOOT_LRUN_Exported_Functions Boot LRUN exported functions
* @{
*/
BOOTStatus_TypeDef BOOT_Application(void)
{
BOOTStatus_TypeDef retr;
/* mount the memory */
retr = MapMemory();
if (BOOT_OK == retr)
{
retr = CopyApplication();
if (BOOT_OK == retr)
{
/* jump on the application */
retr = JumpToApplication();
}
}
return retr;
}
/**
* @}
*/
/**
* @defgroup BOOT_LRUN_Private_Functions Boot LRUN private functions
* @{
*/
/**
* @brief this function maps the memory
* @return @ref BOOTStatus_TypeDef
*/
BOOTStatus_TypeDef MapMemory(void)
{
BOOTStatus_TypeDef retr = BOOT_OK;
uint32_t BaseAddress = 0;
/* Map all the memory */
for (uint8_t index = 0; index < (sizeof(extmem_list_config) / sizeof(EXTMEM_DefinitionTypeDef)); index++)
{
switch(EXTMEM_GetMapAddress(index, &BaseAddress))
{
case EXTMEM_OK :{
if (EXTMEM_MemoryMappedMode(index, EXTMEM_ENABLE) != EXTMEM_OK)
{
retr = BOOT_ERROR_MAPPEDMODEFAIL;
}
break;
}
case EXTMEM_ERROR_NOTSUPPORTED :{
/* the memory doesn't support map mode, nothing to do */
break;
}
default :{
retr = BOOT_ERROR_NOBASEADDRESS;
break;
}
}
}
return retr;
}
/**
* @brief This function copy the data from source to destination
* @return @ref BOOTStatus_TypeDef
*/
BOOTStatus_TypeDef CopyApplication(void)
{
BOOTStatus_TypeDef retr = BOOT_OK;
uint8_t *source;
uint8_t *destination;
uint32_t MapAddress;
uint32_t img_size;
#if defined(EXTMEM_LRUN_DESTINATION_INTERNAL)
/* this case correspond to copy the SW from external memory into internal memory */
destination = (uint8_t *)EXTMEM_LRUN_DESTINATION_ADDRESS;
#else
if (EXTMEM_OK != EXTMEM_GetMapAddress(EXTMEM_LRUN_DESTINATION, &MapAddress))
{
return BOOT_ERROR_MAPPEDMODEFAIL;
}
destination = (uint8_t *)(MapAddress + EXTMEM_LRUN_DESTINATION_ADDRESS);
#endif
/* get the map address of the source memory */
switch(EXTMEM_GetMapAddress(EXTMEM_LRUN_SOURCE, &MapAddress)){
case EXTMEM_OK :{
/* manage the copy in mapped mode */
source = (uint8_t*)(MapAddress + EXTMEM_LRUN_SOURCE_ADDRESS);
img_size = BOOT_GetApplicationSize((uint32_t) source);
/* copy form source to destination in mapped mode */
for (uint32_t index=0; index < img_size; index++)
{
destination[index] = source[index];
}
#if defined(EXTMEM_LRUN_TZ_ENABLE_NS)
source = (uint8_t*)(MapAddress + EXTMEM_LRUN_SOURCE_ADDRESS_NS);
img_size = BOOT_GetApplicationSize((uint32_t) source);
destination = (uint8_t *)EXTMEM_LRUN_DESTINATION_ADDRESS_NS;
/* copy Non-Secure form source to destination in mapped mode */
for (uint32_t index=0; index < img_size; index++)
{
destination[index] = source[index];
}
#endif
break;
}
case EXTMEM_ERROR_NOTSUPPORTED:{
img_size = BOOT_GetApplicationSize(EXTMEM_LRUN_SOURCE_ADDRESS);
/* manage the copy using EXTMEM_Read */
if (EXTMEM_OK != EXTMEM_Read(EXTMEM_LRUN_SOURCE, EXTMEM_LRUN_SOURCE_ADDRESS, destination, img_size))
{
retr = BOOT_ERROR_COPY;
}
#if defined(EXTMEM_LRUN_TZ_ENABLE_NS)
img_size = BOOT_GetApplicationSize(EXTMEM_LRUN_SOURCE_ADDRESS_NS);
destination = (uint8_t *)EXTMEM_LRUN_DESTINATION_ADDRESS_NS;
/* copy Non-Secure form source to destination in mapped mode */
if (EXTMEM_OK != EXTMEM_Read(EXTMEM_LRUN_SOURCE, EXTMEM_LRUN_SOURCE_ADDRESS_NS, destination, img_size))
{
retr = BOOT_ERROR_COPY;
}
#endif
break;
}
default :{
/* return an error */
retr = BOOT_ERROR_MAPPEDMODEFAIL;
break;
}
}
return retr;
}
/**
* @brief This function jumps to the application through its vector table
* @return @ref BOOTStatus_TypeDef
*/
BOOTStatus_TypeDef JumpToApplication(void)
{
uint32_t primask_bit;
typedef void (*pFunction)(void);
static pFunction JumpToApp;
uint32_t Application_vector;
/* Suspend SysTick */
HAL_SuspendTick();
#if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
/* if I-Cache is enabled, disable I-Cache-----------------------------------*/
if (SCB->CCR & SCB_CCR_IC_Msk)
{
SCB_DisableICache();
}
#endif /* defined(ICACHE_PRESENT) && (ICACHE_PRESENT == 1U) */
#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
/* if D-Cache is enabled, disable D-Cache-----------------------------------*/
if (SCB->CCR & SCB_CCR_DC_Msk)
{
SCB_DisableDCache();
}
#endif /* defined(DCACHE_PRESENT) && (DCACHE_PRESENT == 1U) */
/* Initialize user application's Stack Pointer & Jump to user application */
primask_bit = __get_PRIMASK();
__disable_irq();
Application_vector = BOOT_GetApplicationVectorTable();
SCB->VTOR = (uint32_t)Application_vector;
JumpToApp = (pFunction) (*(__IO uint32_t *)(Application_vector + 4));
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
/* on ARM v8m, set MSPLIM before setting MSP to avoid unwanted stack overflow faults */
__set_MSPLIM(0x00000000);
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
__set_MSP(*(__IO uint32_t*)Application_vector);
/* Re-enable the interrupts */
__set_PRIMASK(primask_bit);
JumpToApp();
return BOOT_OK;
}
__weak uint32_t BOOT_GetApplicationSize(uint32_t img_addr)
{
UNUSED(img_addr);
return EXTMEM_LRUN_SOURCE_SIZE;
}
__weak uint32_t BOOT_GetApplicationVectorTable(void)
{
uint32_t vector_table;
#if defined(EXTMEM_LRUN_DESTINATION_INTERNAL)
vector_table = EXTMEM_LRUN_DESTINATION_ADDRESS;
#else
if (EXTMEM_OK != EXTMEM_GetMapAddress(EXTMEM_LRUN_DESTINATION, &vector_table))
{
return 0xffffffff;
}
vector_table += EXTMEM_LRUN_DESTINATION_ADDRESS;
#endif
vector_table += EXTMEM_HEADER_OFFSET;
return vector_table;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/