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