1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "spu.h"
18 #include "region_defs.h"
19
20 /* Platform-specific configuration */
21 #define FLASH_SECURE_ATTRIBUTION_REGION_SIZE SPU_FLASH_REGION_SIZE
22 #define SRAM_SECURE_ATTRIBUTION_REGION_SIZE SPU_SRAM_REGION_SIZE
23
24 #define FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID 0
25 #define SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID 64
26
27 #define NUM_FLASH_SECURE_ATTRIBUTION_REGIONS \
28 (FLASH_TOTAL_SIZE / FLASH_SECURE_ATTRIBUTION_REGION_SIZE)
29 #define NUM_SRAM_SECURE_ATTRIBUTION_REGIONS \
30 (TOTAL_RAM_SIZE / SRAM_SECURE_ATTRIBUTION_REGION_SIZE)
31
32 #define DEVICE_FLASH_BASE_ADDRESS FLASH_BASE_ADDRESS
33 #define DEVICE_SRAM_BASE_ADDRESS SRAM_BASE_ADDRESS
34
35 /* Convenience macros for SPU Non-Secure Callable (NCS) attribution */
36
37 /*
38 * Determine the SPU Region number the given address belongs to.
39 *
40 * addr shall be a valid flash memory address
41 */
42 #define FLASH_NSC_REGION_FROM_ADDR(addr) \
43 ((uint32_t)addr / FLASH_SECURE_ATTRIBUTION_REGION_SIZE)
44
45 /*
46 * Determine the NSC region size based on a given NCS region base address.
47 */
48 #define FLASH_NSC_SIZE_FROM_ADDR(addr) (FLASH_SECURE_ATTRIBUTION_REGION_SIZE \
49 - (((uint32_t)(addr)) % FLASH_SECURE_ATTRIBUTION_REGION_SIZE))
50
51 /*
52 * Determine the encoded the SPU NCS Region Size value,
53 * based on the absolute NCS region size in bytes.
54 *
55 * size shall be a valid SPU NCS Region size value
56 */
57 #define FLASH_NSC_SIZE_REG(size) ((31 - __builtin_clz(size)) - 4)
58
59
spu_enable_interrupts(void)60 void spu_enable_interrupts(void)
61 {
62 nrf_spu_int_enable(NRF_SPU,
63 NRF_SPU_INT_FLASHACCERR_MASK |
64 NRF_SPU_INT_RAMACCERR_MASK |
65 NRF_SPU_INT_PERIPHACCERR_MASK);
66 }
67
spu_events_get(void)68 uint32_t spu_events_get(void)
69 {
70 uint32_t events = 0;
71
72 if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_RAMACCERR)) {
73 events |= SPU_EVENT_RAMACCERR;
74 }
75 if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR)) {
76 events |= SPU_EVENT_FLASHACCERR;
77 }
78 if (nrf_spu_event_check(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR)) {
79 events |= SPU_EVENT_PERIPHACCERR;
80 }
81
82 return events;
83 }
84
spu_clear_events(void)85 void spu_clear_events(void)
86 {
87 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_RAMACCERR);
88 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR);
89 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR);
90 }
91
92 #if defined(REGION_MCUBOOT_ADDRESS) || defined(REGION_B0_ADDRESS) || defined(REGION_S0_ADDRESS) || defined(REGION_S1_ADDRESS)
spu_region_is_flash_region_in_address_range(uint8_t region_id,uint32_t start_address,uint32_t end_address)93 static bool spu_region_is_flash_region_in_address_range(uint8_t region_id, uint32_t start_address, uint32_t end_address)
94 {
95 size_t start_id = (start_address - DEVICE_FLASH_BASE_ADDRESS) / FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
96 size_t end_id = (end_address - DEVICE_FLASH_BASE_ADDRESS) / FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
97 return region_id >= start_id && region_id <= end_id;
98 }
99 #endif
100
101 #if defined(REGION_PCD_SRAM_ADDRESS)
spu_region_is_sram_region_in_address_range(uint8_t region_id,uint32_t start_address,uint32_t end_address)102 static bool spu_region_is_sram_region_in_address_range(uint8_t region_id, uint32_t start_address, uint32_t end_address)
103 {
104 size_t start_id = (start_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
105 size_t end_id = (end_address - DEVICE_SRAM_BASE_ADDRESS) / SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
106 return region_id >= start_id && region_id <= end_id;
107 }
108 #endif
109
spu_region_is_bootloader_region(NRF_SPU_Type * p_reg,uint8_t region_id)110 static bool spu_region_is_bootloader_region(NRF_SPU_Type * p_reg, uint8_t region_id)
111 {
112 bool is_bootloader = false;
113
114 #ifdef REGION_MCUBOOT_ADDRESS
115 is_bootloader = is_bootloader || spu_region_is_flash_region_in_address_range(region_id, REGION_MCUBOOT_ADDRESS, REGION_MCUBOOT_END_ADDRESS);
116 #endif
117 #ifdef REGION_B0_ADDRESS
118 is_bootloader = is_bootloader || spu_region_is_flash_region_in_address_range(region_id, REGION_B0_ADDRESS, REGION_B0_END_ADDRESS);
119 #endif
120 #ifdef REGION_S0_ADDRESS
121 is_bootloader = is_bootloader || spu_region_is_flash_region_in_address_range(region_id, REGION_S0_ADDRESS, REGION_S0_END_ADDRESS);
122 #endif
123 #ifdef REGION_S1_ADDRESS
124 is_bootloader = is_bootloader || spu_region_is_flash_region_in_address_range(region_id, REGION_S1_ADDRESS, REGION_S1_END_ADDRESS);
125 #endif
126
127 return is_bootloader;
128 }
129
spu_region_is_pcd_region(NRF_SPU_Type * p_reg,uint8_t region_id)130 static bool spu_region_is_pcd_region(NRF_SPU_Type * p_reg, uint8_t region_id)
131 {
132 bool is_pcd = false;
133
134 #ifdef PM_PCD_SRAM_ADDRESS
135 is_pcd = is_pcd || spu_region_is_sram_region_in_address_range(region_id, PM_PCD_SRAM_ADDRESS, PM_PCD_SRAM_END_ADDRESS);
136 #endif
137
138 return is_pcd;
139 }
140
spu_regions_reset_unlocked_secure(void)141 void spu_regions_reset_unlocked_secure(void)
142 {
143 for (size_t i = 0; i < NUM_FLASH_SECURE_ATTRIBUTION_REGIONS ; i++) {
144 if (!spu_region_is_bootloader_region(NRF_SPU, i)) {
145 nrf_spu_flashregion_set(NRF_SPU, i,
146 SPU_SECURE_ATTR_SECURE,
147 NRF_SPU_MEM_PERM_READ
148 | NRF_SPU_MEM_PERM_WRITE
149 | NRF_SPU_MEM_PERM_EXECUTE,
150 SPU_LOCK_CONF_UNLOCKED);
151 }
152 }
153
154 for (size_t i = 0; i < NUM_SRAM_SECURE_ATTRIBUTION_REGIONS ; i++) {
155 if (!spu_region_is_pcd_region(NRF_SPU, i)) {
156 nrf_spu_ramregion_set(NRF_SPU, i,
157 SPU_SECURE_ATTR_SECURE,
158 NRF_SPU_MEM_PERM_READ
159 | NRF_SPU_MEM_PERM_WRITE
160 | NRF_SPU_MEM_PERM_EXECUTE,
161 SPU_LOCK_CONF_UNLOCKED);
162 }
163 }
164 }
165
spu_regions_flash_config(uint32_t start_addr,uint32_t limit_addr,bool secure_attr,uint32_t permissions,bool lock_conf)166 void spu_regions_flash_config(uint32_t start_addr, uint32_t limit_addr, bool secure_attr,
167 uint32_t permissions, bool lock_conf)
168 {
169 /* Determine start and last flash region number */
170 size_t start_id =
171 (start_addr - DEVICE_FLASH_BASE_ADDRESS) /
172 FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
173 size_t last_id =
174 (limit_addr - DEVICE_FLASH_BASE_ADDRESS) /
175 FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
176
177 /* Configure all flash regions between start_id and last_id */
178 for (size_t i = start_id; i <= last_id; i++) {
179 nrf_spu_flashregion_set(NRF_SPU, i, secure_attr, permissions, lock_conf);
180 }
181 }
182
spu_regions_sram_config(uint32_t start_addr,uint32_t limit_addr,bool secure_attr,uint32_t permissions,bool lock_conf)183 void spu_regions_sram_config(uint32_t start_addr, uint32_t limit_addr, bool secure_attr,
184 uint32_t permissions, bool lock_conf)
185 {
186 /* Determine start and last ram region number */
187 size_t start_id =
188 (start_addr - DEVICE_SRAM_BASE_ADDRESS) /
189 SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
190 size_t last_id =
191 (limit_addr - DEVICE_SRAM_BASE_ADDRESS) /
192 SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
193
194 /* Configure all ram regions between start_id and last_id */
195 for (size_t i = start_id; i <= last_id; i++) {
196 nrf_spu_ramregion_set(NRF_SPU, i, secure_attr, permissions, lock_conf);
197 }
198 }
199
spu_regions_flash_config_non_secure_callable(uint32_t start_addr,uint32_t limit_addr)200 void spu_regions_flash_config_non_secure_callable(uint32_t start_addr,
201 uint32_t limit_addr)
202 {
203 size_t size = limit_addr - start_addr + 1;
204
205 uint32_t nsc_size = FLASH_NSC_SIZE_FROM_ADDR(start_addr);
206
207 /* Check Non-Secure Callable region possible overflow */
208 NRFX_ASSERT(size <= nsc_size);
209
210 /* Check Non-Secure Callable region ending on SPU boundary */
211 NRFX_ASSERT(((start_addr + nsc_size) %
212 FLASH_SECURE_ATTRIBUTION_REGION_SIZE) == 0);
213
214 /* Check Non-Secure Callable region power-of-2 size compliance */
215 NRFX_ASSERT((nsc_size & (nsc_size - 1)) == 0);
216
217 /* Check Non-Secure Callable region size is within [32, 4096] range */
218 NRFX_ASSERT((nsc_size >= 32) && (nsc_size <= 4096));
219
220 nrf_spu_flashnsc_set(NRF_SPU, 0,
221 FLASH_NSC_SIZE_REG(nsc_size),
222 FLASH_NSC_REGION_FROM_ADDR(start_addr),
223 SPU_LOCK_CONF_LOCKED);
224 }
225
spu_regions_flash_get_base_address_in_region(uint32_t region_id)226 uint32_t spu_regions_flash_get_base_address_in_region(uint32_t region_id)
227 {
228 return FLASH_BASE_ADDRESS +
229 ((region_id - FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID) *
230 FLASH_SECURE_ATTRIBUTION_REGION_SIZE);
231 }
232
spu_regions_flash_get_last_address_in_region(uint32_t region_id)233 uint32_t spu_regions_flash_get_last_address_in_region(uint32_t region_id)
234 {
235 return FLASH_BASE_ADDRESS +
236 ((region_id - FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID + 1) *
237 FLASH_SECURE_ATTRIBUTION_REGION_SIZE) - 1;
238 }
239
spu_regions_flash_get_start_id(void)240 uint32_t spu_regions_flash_get_start_id(void) {
241
242 return FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID;
243 }
244
spu_regions_flash_get_last_id(void)245 uint32_t spu_regions_flash_get_last_id(void) {
246
247 return FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID +
248 NUM_FLASH_SECURE_ATTRIBUTION_REGIONS - 1;
249 }
250
spu_regions_flash_get_region_size(void)251 uint32_t spu_regions_flash_get_region_size(void) {
252
253 return FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
254 }
255
spu_regions_sram_get_base_address_in_region(uint32_t region_id)256 uint32_t spu_regions_sram_get_base_address_in_region(uint32_t region_id)
257 {
258 return SRAM_BASE_ADDRESS +
259 ((region_id - SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID) *
260 SRAM_SECURE_ATTRIBUTION_REGION_SIZE);
261 }
262
spu_regions_sram_get_last_address_in_region(uint32_t region_id)263 uint32_t spu_regions_sram_get_last_address_in_region(uint32_t region_id)
264 {
265 return SRAM_BASE_ADDRESS +
266 ((region_id - SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID + 1) *
267 SRAM_SECURE_ATTRIBUTION_REGION_SIZE) - 1;
268 }
269
spu_regions_sram_get_start_id(void)270 uint32_t spu_regions_sram_get_start_id(void) {
271
272 return SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID;
273 }
274
spu_regions_sram_get_last_id(void)275 uint32_t spu_regions_sram_get_last_id(void) {
276
277 return SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID +
278 NUM_SRAM_SECURE_ATTRIBUTION_REGIONS - 1;
279 }
280
spu_regions_sram_get_region_size(void)281 uint32_t spu_regions_sram_get_region_size(void) {
282
283 return SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
284 }
285
spu_peripheral_config_secure(const uint8_t periph_id,bool periph_lock)286 void spu_peripheral_config_secure(const uint8_t periph_id, bool periph_lock)
287 {
288 /* ASSERT checking that this is not an explicit Non-Secure peripheral */
289 NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM &
290 SPU_PERIPHID_PERM_SECUREMAPPING_Msk) !=
291 (SPU_PERIPHID_PERM_SECUREMAPPING_NonSecure <<
292 SPU_PERIPHID_PERM_SECUREMAPPING_Pos));
293
294 nrf_spu_peripheral_set(NRF_SPU, periph_id,
295 1 /* Secure */,
296 1 /* Secure DMA */,
297 periph_lock);
298 }
299
spu_peripheral_config_non_secure(const uint8_t periph_id,bool periph_lock)300 void spu_peripheral_config_non_secure(const uint8_t periph_id, bool periph_lock)
301 {
302 /* ASSERT checking that this is not an explicit Secure peripheral */
303 NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM &
304 SPU_PERIPHID_PERM_SECUREMAPPING_Msk) !=
305 (SPU_PERIPHID_PERM_SECUREMAPPING_Secure <<
306 SPU_PERIPHID_PERM_SECUREMAPPING_Pos));
307
308 nrf_spu_peripheral_set(NRF_SPU, periph_id,
309 0 /* Non-Secure */,
310 0 /* Non-Secure DMA */,
311 periph_lock);
312 }
313