Contiki-NG
Loading...
Searching...
No Matches
spu.c
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/* This file has been modified for use in the Contiki-NG operating system. */
18
19#include "spu.h"
20#include "region_defs.h"
21
22/* Platform-specific configuration */
23#define FLASH_SECURE_ATTRIBUTION_REGION_SIZE SPU_FLASH_REGION_SIZE
24#define SRAM_SECURE_ATTRIBUTION_REGION_SIZE SPU_SRAM_REGION_SIZE
25
26#define FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID 0
27#define SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID 64
28
29#define NUM_FLASH_SECURE_ATTRIBUTION_REGIONS \
30 (FLASH_TOTAL_SIZE / FLASH_SECURE_ATTRIBUTION_REGION_SIZE)
31#define NUM_SRAM_SECURE_ATTRIBUTION_REGIONS \
32 (TOTAL_RAM_SIZE / SRAM_SECURE_ATTRIBUTION_REGION_SIZE)
33
34#define DEVICE_FLASH_BASE_ADDRESS FLASH_BASE_ADDRESS
35#define DEVICE_SRAM_BASE_ADDRESS SRAM_BASE_ADDRESS
36
37static int arr_flash[NUM_FLASH_SECURE_ATTRIBUTION_REGIONS];
38static int arr_ram[NUM_FLASH_SECURE_ATTRIBUTION_REGIONS];
39
40/* Convenience macros for SPU Non-Secure Callable (NCS) attribution */
41
42/*
43 * Determine the SPU Region number the given address belongs to.
44 *
45 * addr shall be a valid flash memory address
46 */
47#define FLASH_NSC_REGION_FROM_ADDR(addr) \
48 ((uint32_t)addr / FLASH_SECURE_ATTRIBUTION_REGION_SIZE)
49
50/*
51 * Determine the NSC region size based on a given NCS region base address.
52 */
53#define FLASH_NSC_SIZE_FROM_ADDR(addr) (FLASH_SECURE_ATTRIBUTION_REGION_SIZE - (((uint32_t)(addr)) % FLASH_SECURE_ATTRIBUTION_REGION_SIZE))
54
55/*
56 * Determine the encoded the SPU NCS Region Size value,
57 * based on the absolute NCS region size in bytes.
58 *
59 * size shall be a valid SPU NCS Region size value
60 */
61#define FLASH_NSC_SIZE_REG(size) ((31 - __builtin_clz(size)) - 4)
62
63
64void spu_enable_interrupts(void)
65{
66 nrf_spu_int_enable(NRF_SPU,
67 NRF_SPU_INT_FLASHACCERR_MASK |
68 NRF_SPU_INT_RAMACCERR_MASK |
69 NRF_SPU_INT_PERIPHACCERR_MASK);
70}
71
72void spu_clear_events(void)
73{
74 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_RAMACCERR);
75 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_FLASHACCERR);
76 nrf_spu_event_clear(NRF_SPU, NRF_SPU_EVENT_PERIPHACCERR);
77}
78
79void spu_regions_reset_all_secure(void)
80{
81 for (size_t i = 0; i < NUM_FLASH_SECURE_ATTRIBUTION_REGIONS ; i++) {
82 nrf_spu_flashregion_set(NRF_SPU, i,
83 1 /* Secure */,
84 NRF_SPU_MEM_PERM_READ | NRF_SPU_MEM_PERM_WRITE | NRF_SPU_MEM_PERM_EXECUTE,
85 0 /* No lock */);
86 arr_flash[i] = 1;
87 }
88
89 for (size_t i = 0; i < NUM_SRAM_SECURE_ATTRIBUTION_REGIONS ; i++) {
90 nrf_spu_ramregion_set(NRF_SPU, i,
91 1 /* Secure */,
92 NRF_SPU_MEM_PERM_READ | NRF_SPU_MEM_PERM_WRITE | NRF_SPU_MEM_PERM_EXECUTE,
93 0 /* No lock */);
94 arr_ram[i] = 1;
95 }
96}
97
98void spu_regions_flash_config_non_secure(uint32_t start_addr, uint32_t limit_addr)
99{
100 /* Determine start and last flash region number */
101 size_t start_id =
102 (start_addr - DEVICE_FLASH_BASE_ADDRESS) /
103 FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
104 size_t last_id =
105 (limit_addr - DEVICE_FLASH_BASE_ADDRESS) /
106 FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
107
108 /* Configure all flash regions between start_id and last_id */
109 for (size_t i = start_id; i <= last_id; i++) {
110 nrf_spu_flashregion_set(NRF_SPU, i,
111 0 /* Non-Secure */,
112 NRF_SPU_MEM_PERM_READ | NRF_SPU_MEM_PERM_WRITE | NRF_SPU_MEM_PERM_EXECUTE,
113 1 /* Lock */);
114 arr_flash[i] = 0;
115 }
116}
117
118void spu_regions_flash_config_non_secure_callable(uint32_t start_addr,
119 uint32_t limit_addr)
120{
121 uint32_t nsc_size = FLASH_NSC_SIZE_FROM_ADDR(start_addr);
122
123 /* Check Non-Secure Callable region ending on SPU boundary */
124 NRFX_ASSERT(((start_addr + nsc_size) %
125 FLASH_SECURE_ATTRIBUTION_REGION_SIZE) == 0);
126
127 /* Check Non-Secure Callable region power-of-2 size compliance */
128 NRFX_ASSERT((nsc_size & (nsc_size - 1)) == 0);
129
130 /* Check Non-Secure Callable region size is within [32, 4096] range */
131 NRFX_ASSERT((nsc_size >= 32) && (nsc_size <= 4096));
132
133 nrf_spu_flashnsc_set(NRF_SPU, 0,
134 FLASH_NSC_SIZE_REG(nsc_size),
135 FLASH_NSC_REGION_FROM_ADDR(start_addr),
136 1 /* Lock */);
137}
138
139uint32_t spu_regions_flash_get_base_address_in_region(uint32_t region_id)
140{
141 return FLASH_BASE_ADDRESS +
142 ((region_id - FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID) *
143 FLASH_SECURE_ATTRIBUTION_REGION_SIZE);
144}
145
146uint32_t spu_regions_flash_get_last_address_in_region(uint32_t region_id)
147{
148 return FLASH_BASE_ADDRESS +
149 ((region_id - FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID + 1) *
150 FLASH_SECURE_ATTRIBUTION_REGION_SIZE) - 1;
151}
152
153uint32_t spu_regions_flash_get_start_id(void) {
154
155 return FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID;
156}
157
158uint32_t spu_regions_flash_get_last_id(void) {
159
160 return FLASH_SECURE_ATTRIBUTION_REGIONS_START_ID +
161 NUM_FLASH_SECURE_ATTRIBUTION_REGIONS - 1;
162}
163
164uint32_t spu_regions_flash_get_region_size(void) {
165
166 return FLASH_SECURE_ATTRIBUTION_REGION_SIZE;
167}
168
169void spu_regions_sram_config_non_secure(uint32_t start_addr, uint32_t limit_addr)
170{
171 /* Determine start and last ram region number */
172 size_t start_id =
173 (start_addr - DEVICE_SRAM_BASE_ADDRESS) /
174 SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
175 size_t last_id =
176 (limit_addr - DEVICE_SRAM_BASE_ADDRESS) /
177 SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
178
179 /* Configure all ram regions between start_id and last_id */
180 for (size_t i = start_id; i <= last_id; i++)
181 {
182 nrf_spu_ramregion_set(NRF_SPU, i,
183 0 /* Non-Secure */,
184 NRF_SPU_MEM_PERM_READ | NRF_SPU_MEM_PERM_WRITE | NRF_SPU_MEM_PERM_EXECUTE,
185 1 /* Lock */);
186 arr_ram[i] = 0;
187 }
188}
189
190uint32_t spu_regions_sram_get_base_address_in_region(uint32_t region_id)
191{
192 return SRAM_BASE_ADDRESS +
193 ((region_id - SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID) *
194 SRAM_SECURE_ATTRIBUTION_REGION_SIZE);
195}
196
197uint32_t spu_regions_sram_get_last_address_in_region(uint32_t region_id)
198{
199 return SRAM_BASE_ADDRESS +
200 ((region_id - SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID + 1) *
201 SRAM_SECURE_ATTRIBUTION_REGION_SIZE) - 1;
202}
203
204uint32_t spu_regions_sram_get_start_id(void) {
205
206 return SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID;
207}
208
209uint32_t spu_regions_sram_get_last_id(void) {
210
211 return SRAM_SECURE_ATTRIBUTION_REGIONS_START_ID +
212 NUM_SRAM_SECURE_ATTRIBUTION_REGIONS - 1;
213}
214
215uint32_t spu_regions_sram_get_region_size(void) {
216
217 return SRAM_SECURE_ATTRIBUTION_REGION_SIZE;
218}
219
220void spu_peripheral_config_secure(uint32_t periph_base_addr, bool periph_lock)
221{
222 /* Determine peripheral ID */
223 const uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_addr);
224
225 /* Check that this is not an explicitly Non-Secure peripheral */
226 NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM &
227 SPU_PERIPHID_PERM_SECUREMAPPING_Msk) !=
228 (SPU_PERIPHID_PERM_SECUREMAPPING_NonSecure << SPU_PERIPHID_PERM_SECUREMAPPING_Pos));
229
230 nrf_spu_peripheral_set(NRF_SPU, periph_id,
231 1 /* Secure */,
232 1 /* Secure DMA */,
233 periph_lock);
234}
235
236void spu_peripheral_config_non_secure(uint32_t periph_base_addr, bool periph_lock)
237{
238 /* Determine peripheral ID */
239 const uint8_t periph_id = NRFX_PERIPHERAL_ID_GET(periph_base_addr);
240
241 /* ASSERT checking that this is not an explicit Secure peripheral */
242 NRFX_ASSERT((NRF_SPU->PERIPHID[periph_id].PERM &
243 SPU_PERIPHID_PERM_SECUREMAPPING_Msk) !=
244 (SPU_PERIPHID_PERM_SECUREMAPPING_Secure << SPU_PERIPHID_PERM_SECUREMAPPING_Pos));
245
246 nrf_spu_peripheral_set(NRF_SPU, periph_id,
247 0 /* Non-Secure */,
248 0 /* Non-Secure DMA */,
249 periph_lock);
250}
#define NRFX_ASSERT(expression)
Macro for placing a runtime assertion.
Definition nrfx_glue.h:60