]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/IAR/ARM_CM23/secure/secure_context.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Source / portable / IAR / ARM_CM23 / secure / secure_context.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /* Secure context includes. */\r
29 #include "secure_context.h"\r
30 \r
31 /* Secure heap includes. */\r
32 #include "secure_heap.h"\r
33 \r
34 /* Secure port macros. */\r
35 #include "secure_port_macros.h"\r
36 \r
37 /**\r
38  * @brief CONTROL value for privileged tasks.\r
39  *\r
40  * Bit[0] - 0 --> Thread mode is privileged.\r
41  * Bit[1] - 1 --> Thread mode uses PSP.\r
42  */\r
43 #define securecontextCONTROL_VALUE_PRIVILEGED           0x02\r
44 \r
45 /**\r
46  * @brief CONTROL value for un-privileged tasks.\r
47  *\r
48  * Bit[0] - 1 --> Thread mode is un-privileged.\r
49  * Bit[1] - 1 --> Thread mode uses PSP.\r
50  */\r
51 #define securecontextCONTROL_VALUE_UNPRIVILEGED         0x03\r
52 /*-----------------------------------------------------------*/\r
53 \r
54 /**\r
55  * @brief Structure to represent secure context.\r
56  *\r
57  * @note Since stack grows down, pucStackStart is the highest address while\r
58  * pucStackLimit is the first addess of the allocated memory.\r
59  */\r
60 typedef struct SecureContext\r
61 {\r
62         uint8_t *pucCurrentStackPointer;        /**< Current value of stack pointer (PSP). */\r
63         uint8_t *pucStackLimit;                         /**< Last location of the stack memory (PSPLIM). */\r
64         uint8_t *pucStackStart;                         /**< First location of the stack memory. */\r
65 } SecureContext_t;\r
66 /*-----------------------------------------------------------*/\r
67 \r
68 secureportNON_SECURE_CALLABLE void SecureContext_Init( void )\r
69 {\r
70         uint32_t ulIPSR;\r
71 \r
72         /* Read the Interrupt Program Status Register (IPSR) value. */\r
73         secureportREAD_IPSR( ulIPSR );\r
74 \r
75         /* Do nothing if the processor is running in the Thread Mode. IPSR is zero\r
76          * when the processor is running in the Thread Mode. */\r
77         if( ulIPSR != 0 )\r
78         {\r
79                 /* No stack for thread mode until a task's context is loaded. */\r
80                 secureportSET_PSPLIM( securecontextNO_STACK );\r
81                 secureportSET_PSP( securecontextNO_STACK );\r
82 \r
83                 #if( configENABLE_MPU == 1 )\r
84                 {\r
85                         /* Configure thread mode to use PSP and to be unprivileged. */\r
86                         secureportSET_CONTROL( securecontextCONTROL_VALUE_UNPRIVILEGED );\r
87                 }\r
88                 #else /* configENABLE_MPU */\r
89                 {\r
90                         /* Configure thread mode to use PSP and to be privileged.. */\r
91                         secureportSET_CONTROL( securecontextCONTROL_VALUE_PRIVILEGED );\r
92                 }\r
93                 #endif /* configENABLE_MPU */\r
94         }\r
95 }\r
96 /*-----------------------------------------------------------*/\r
97 \r
98 #if( configENABLE_MPU == 1 )\r
99         secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize, uint32_t ulIsTaskPrivileged )\r
100 #else /* configENABLE_MPU */\r
101         secureportNON_SECURE_CALLABLE SecureContextHandle_t SecureContext_AllocateContext( uint32_t ulSecureStackSize )\r
102 #endif /* configENABLE_MPU */\r
103 {\r
104         uint8_t *pucStackMemory = NULL;\r
105         uint32_t ulIPSR;\r
106         SecureContextHandle_t xSecureContextHandle = NULL;\r
107         #if( configENABLE_MPU == 1 )\r
108                 uint32_t *pulCurrentStackPointer = NULL;\r
109         #endif /* configENABLE_MPU */\r
110 \r
111         /* Read the Interrupt Program Status Register (IPSR) value. */\r
112         secureportREAD_IPSR( ulIPSR );\r
113 \r
114         /* Do nothing if the processor is running in the Thread Mode. IPSR is zero\r
115          * when the processor is running in the Thread Mode. */\r
116         if( ulIPSR != 0 )\r
117         {\r
118                 /* Allocate the context structure. */\r
119                 xSecureContextHandle = ( SecureContextHandle_t ) pvPortMalloc( sizeof( SecureContext_t ) );\r
120 \r
121                 if( xSecureContextHandle != NULL )\r
122                 {\r
123                         /* Allocate the stack space. */\r
124                         pucStackMemory = pvPortMalloc( ulSecureStackSize );\r
125 \r
126                         if( pucStackMemory != NULL )\r
127                         {\r
128                                 /* Since stack grows down, the starting point will be the last\r
129                                  * location. Note that this location is next to the last\r
130                                  * allocated byte because the hardware decrements the stack\r
131                                  * pointer before writing i.e. if stack pointer is 0x2, a push\r
132                                  * operation will decrement the stack pointer to 0x1 and then\r
133                                  * write at 0x1. */\r
134                                 xSecureContextHandle->pucStackStart = pucStackMemory + ulSecureStackSize;\r
135 \r
136                                 /* The stack cannot go beyond this location. This value is\r
137                                  * programmed in the PSPLIM register on context switch.*/\r
138                                 xSecureContextHandle->pucStackLimit = pucStackMemory;\r
139 \r
140                                 #if( configENABLE_MPU == 1 )\r
141                                 {\r
142                                         /* Store the correct CONTROL value for the task on the stack.\r
143                                          * This value is programmed in the CONTROL register on\r
144                                          * context switch. */\r
145                                         pulCurrentStackPointer = ( uint32_t * ) xSecureContextHandle->pucStackStart;\r
146                                         pulCurrentStackPointer--;\r
147                                         if( ulIsTaskPrivileged )\r
148                                         {\r
149                                                 *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_PRIVILEGED;\r
150                                         }\r
151                                         else\r
152                                         {\r
153                                                 *( pulCurrentStackPointer ) = securecontextCONTROL_VALUE_UNPRIVILEGED;\r
154                                         }\r
155 \r
156                                         /* Store the current stack pointer. This value is programmed in\r
157                                          * the PSP register on context switch. */\r
158                                         xSecureContextHandle->pucCurrentStackPointer = ( uint8_t * ) pulCurrentStackPointer;\r
159                                 }\r
160                                 #else /* configENABLE_MPU */\r
161                                 {\r
162                                         /* Current SP is set to the starting of the stack. This\r
163                                          * value programmed in the PSP register on context switch. */\r
164                                         xSecureContextHandle->pucCurrentStackPointer = xSecureContextHandle->pucStackStart;\r
165 \r
166                                 }\r
167                                 #endif /* configENABLE_MPU */\r
168                         }\r
169                         else\r
170                         {\r
171                                 /* Free the context to avoid memory leak and make sure to return\r
172                                  * NULL to indicate failure. */\r
173                                 vPortFree( xSecureContextHandle );\r
174                                 xSecureContextHandle = NULL;\r
175                         }\r
176                 }\r
177         }\r
178 \r
179         return xSecureContextHandle;\r
180 }\r
181 /*-----------------------------------------------------------*/\r
182 \r
183 secureportNON_SECURE_CALLABLE void SecureContext_FreeContext( SecureContextHandle_t xSecureContextHandle )\r
184 {\r
185         uint32_t ulIPSR;\r
186 \r
187         /* Read the Interrupt Program Status Register (IPSR) value. */\r
188         secureportREAD_IPSR( ulIPSR );\r
189 \r
190         /* Do nothing if the processor is running in the Thread Mode. IPSR is zero\r
191          * when the processor is running in the Thread Mode. */\r
192         if( ulIPSR != 0 )\r
193         {\r
194                 /* Ensure that valid parameters are passed. */\r
195                 secureportASSERT( xSecureContextHandle != NULL );\r
196 \r
197                 /* Free the stack space. */\r
198                 vPortFree( xSecureContextHandle->pucStackLimit );\r
199 \r
200                 /* Free the context itself. */\r
201                 vPortFree( xSecureContextHandle );\r
202         }\r
203 }\r
204 /*-----------------------------------------------------------*/\r