1 /*
2  * Copyright (c) 2019-2020, Cypress Semiconductor Corporation. All rights reserved.
3  * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef __SMPU_CONFIG_H__
21 #define __SMPU_CONFIG_H__
22 
23 #include "flash_layout.h"
24 #include "region_defs.h"
25 
26 #include "cy_prot.h"
27 
28 /* This macro depends on the actual CY_PROT_REGIONSIZE_XXX values */
29 #define REGIONSIZE_TO_BYTES(X)      (1UL << (1 + (X)))
30 
31 /* This triplet of flag values indicates that the actual values
32  * must be retrieved from provisioning data at runtime.
33  */
34 #define SMPU_DYNAMIC_BASE       ((void *)-1)
35 #define SMPU_DYNAMIC_REGIONSIZE ((cy_en_prot_size_t)0)
36 #define SMPU_DYNAMIC_SUBREGIONS (0)
37 
38 /* The actual SMPU configs */
39 
40 /* SMPU configs can only be changed by privileged secure PC=1 bus masters */
41 #define COMMON_SMPU_MASTER_CONFIG {\
42     .userPermission = CY_PROT_PERM_R, \
43     .privPermission = CY_PROT_PERM_RW, \
44     .secure = false, \
45     .pcMatch = false, \
46     .pcMask = ONLY_BL2_SPM_MASK, \
47 }
48 
49 /* SMPU0 - secure primary image in Flash */
50 #define SMPU0_BASE          S_ROM_ALIAS(SECURE_IMAGE_OFFSET)
51 #define SMPU0_REGIONSIZE    PROT_SIZE_512KB_BIT_SHIFT
52 #define SMPU0_SUBREGION_DIS (CY_PROT_SUBREGION_DIS5 | \
53                              CY_PROT_SUBREGION_DIS6 | \
54                              CY_PROT_SUBREGION_DIS7)
55 #define SMPU0_SLAVE_CONFIG {\
56     .address = (void *)SMPU0_BASE, \
57     .regionSize = (cy_en_prot_size_t) SMPU0_REGIONSIZE, \
58     .subregions = SMPU0_SUBREGION_DIS, \
59     .userPermission = CY_PROT_PERM_RX, \
60     .privPermission = CY_PROT_PERM_RX, \
61     .secure = false, \
62     .pcMatch = false, \
63     .pcMask = SECURE_PCS_MASK, \
64 }
65 #define SMPU0_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
66 
67 /* SMPU requires base address aligned to size */
68 #if SMPU0_BASE % REGIONSIZE_TO_BYTES(SMPU0_REGIONSIZE)
69 #error "Flash layout has changed - SMPU0 needs updating"
70 #endif
71 
72 /*
73  * SMPU0 protected area should be exactly the size of the secure primary image
74  */
75 #if FLASH_S_PARTITION_SIZE != (5 * REGIONSIZE_TO_BYTES(SMPU0_REGIONSIZE)/8)
76 #error "Flash layout has changed - FLASH_S_PARTITION_SIZE isn't 5/8 of SMPU0_REGIONSIZE"
77 #endif
78 
79 /* SMPU1 - Internal Trusted Storage in Flash */
80 /* Dynamically configured from provisioning data */
81 #define ITS_SMPU_STRUCT     PROT_SMPU_SMPU_STRUCT1
82 #define SMPU1_SLAVE_CONFIG {\
83     .address = SMPU_DYNAMIC_BASE, \
84     .regionSize = SMPU_DYNAMIC_REGIONSIZE, \
85     .subregions = SMPU_DYNAMIC_SUBREGIONS, \
86     .userPermission = CY_PROT_PERM_DISABLED, \
87     .privPermission = CY_PROT_PERM_RW, \
88     .secure = false, \
89     .pcMatch = false, \
90     .pcMask = SECURE_PCS_MASK, \
91 }
92 #define SMPU1_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
93 
94 /* SMPU2 - NV counters in Flash */
95 /* Dynamically configured from provisioning data */
96 #define NVC_SMPU_STRUCT     PROT_SMPU_SMPU_STRUCT2
97 #define SMPU2_SLAVE_CONFIG {\
98     .address = SMPU_DYNAMIC_BASE, \
99     .regionSize = SMPU_DYNAMIC_REGIONSIZE, \
100     .subregions = SMPU_DYNAMIC_SUBREGIONS, \
101     .userPermission = CY_PROT_PERM_DISABLED, \
102     .privPermission = CY_PROT_PERM_RW, \
103     .secure = false, \
104     .pcMatch = false, \
105     .pcMask = SECURE_PCS_MASK, \
106 }
107 #define SMPU2_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
108 
109 /* SMPU3 - PS in Flash */
110 /* Dynamically configured from provisioning data */
111 #define PS_SMPU_STRUCT      PROT_SMPU_SMPU_STRUCT3
112 #define SMPU3_SLAVE_CONFIG {\
113     .address = SMPU_DYNAMIC_BASE, \
114     .regionSize = SMPU_DYNAMIC_REGIONSIZE, \
115     .subregions = SMPU_DYNAMIC_SUBREGIONS, \
116     .userPermission = CY_PROT_PERM_RW, \
117     .privPermission = CY_PROT_PERM_RW, \
118     .secure = false, \
119     .pcMatch = false, \
120     .pcMask = SECURE_PCS_MASK, \
121 }
122 #define SMPU3_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
123 
124 /* SMPU6 - 32KB of unprivileged secure data in SRAM */
125 #define SMPU6_BASE         S_DATA_START
126 #define SMPU6_REGIONSIZE   PROT_SIZE_32KB_BIT_SHIFT
127 #define SMPU6_SLAVE_CONFIG {\
128     .address = (void *)SMPU6_BASE, \
129     .regionSize = (cy_en_prot_size_t) SMPU6_REGIONSIZE, \
130     .subregions = ALL_ENABLED, \
131     .userPermission = CY_PROT_PERM_RW, \
132     .privPermission = CY_PROT_PERM_RW, \
133     .secure = false, \
134     .pcMatch = false, \
135     .pcMask = SECURE_PCS_MASK, \
136 }
137 #define SMPU6_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
138 
139 /* SMPU requires base address aligned to size */
140 #if SMPU6_BASE % REGIONSIZE_TO_BYTES(SMPU6_REGIONSIZE)
141 #error "Flash layout has changed - SMPU6 needs updating"
142 #endif
143 
144 /* SMPU6 should exactly cover the unprivileged secure SRAM */
145 #if REGIONSIZE_TO_BYTES(SMPU6_REGIONSIZE) != S_UNPRIV_DATA_SIZE
146 #error "SMPU6_REGIONSIZE should match S_UNPRIV_DATA_SIZE"
147 #endif
148 
149 /* SMPUs 7 and 8 - 160KB of privileged secure data at S_DATA_PRIV_START in SRAM */
150 #define SMPU7_BASE          S_RAM_ALIAS(0)
151 #define SMPU7_REGIONSIZE    PROT_SIZE_128KB_BIT_SHIFT
152 #define SMPU7_SUBREGION_DIS (CY_PROT_SUBREGION_DIS0 | \
153                              CY_PROT_SUBREGION_DIS1)
154 #define SMPU7_SLAVE_CONFIG {\
155     .address = (void *)SMPU7_BASE, \
156     .regionSize = (cy_en_prot_size_t) SMPU7_REGIONSIZE, \
157     .subregions = SMPU7_SUBREGION_DIS, \
158     .userPermission = CY_PROT_PERM_DISABLED, \
159     .privPermission = CY_PROT_PERM_RW, \
160     .secure = false, \
161     .pcMatch = false, \
162     .pcMask = SECURE_PCS_MASK, \
163 }
164 #define SMPU7_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
165 
166 /* SMPU requires base address aligned to size */
167 #if SMPU7_BASE % REGIONSIZE_TO_BYTES(SMPU7_REGIONSIZE)
168 #error "Flash layout has changed - SMPU7 needs updating"
169 #endif
170 
171 /*
172  * S_DATA_PRIV_START must equal the base address of subregion 2 of
173  * SMPU7
174  */
175 #if S_DATA_PRIV_START != (SMPU7_BASE + \
176                           (2 * REGIONSIZE_TO_BYTES(SMPU7_REGIONSIZE) / 8))
177 #error "Flash layout has changed - S_DATA_PRIV_START isn't subregion 2 of SMPU7"
178 #endif
179 
180 #define SMPU8_BASE          S_RAM_ALIAS(0x20000)
181 #define SMPU8_REGIONSIZE    PROT_SIZE_64KB_BIT_SHIFT
182 #define SMPU8_SLAVE_CONFIG {\
183     .address = (void *)SMPU8_BASE, \
184     .regionSize = (cy_en_prot_size_t) SMPU8_REGIONSIZE, \
185     .subregions = ALL_ENABLED, \
186     .userPermission = CY_PROT_PERM_DISABLED, \
187     .privPermission = CY_PROT_PERM_RW, \
188     .secure = false, \
189     .pcMatch = false, \
190     .pcMask = SECURE_PCS_MASK, \
191 }
192 #define SMPU8_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
193 
194 /* SMPU requires base address aligned to size */
195 #if SMPU8_BASE % REGIONSIZE_TO_BYTES(SMPU8_REGIONSIZE)
196 #error "Flash layout has changed - SMPU8 needs updating"
197 #endif
198 
199 /*
200  * SMPU8 must immediately follow SMPU7
201  */
202 #if SMPU8_BASE != (SMPU7_BASE + REGIONSIZE_TO_BYTES(SMPU7_REGIONSIZE))
203 #error "Flash layout has changed - SMPU8 doesn't immediately follow SMPU7"
204 #endif
205 
206 /* SMPU7 and SMPU8 should exactly cover the privileged secure SRAM which
207  * consists of S_PRIV_DATA and S_RAM_CODE
208  */
209 #if ((6*REGIONSIZE_TO_BYTES(SMPU7_REGIONSIZE)/8) + \
210      REGIONSIZE_TO_BYTES(SMPU8_REGIONSIZE)) != \
211      (S_PRIV_DATA_SIZE + S_RAM_CODE_SIZE)
212 #error "SMPU7+SMPU8 REGIONSIZE should match privileged secure SRAM size"
213 #endif
214 
215 /* SMPU9 - 2KB of privileged executable data in SRAM
216  * Note: Region resides in subregion 7 of SMPU 8*/
217 #define SMPU9_BASE         S_RAM_CODE_START
218 #define SMPU9_REGIONSIZE   PROT_SIZE_2KB_BIT_SHIFT
219 #define SMPU9_SLAVE_CONFIG {\
220     .address = (void *)SMPU9_BASE, \
221     .regionSize = (cy_en_prot_size_t) SMPU9_REGIONSIZE, \
222     .subregions = ALL_ENABLED, \
223     .userPermission = CY_PROT_PERM_DISABLED, \
224     .privPermission = CY_PROT_PERM_RX, \
225     .secure = false, \
226     .pcMatch = false, \
227     .pcMask = SECURE_PCS_MASK, \
228 }
229 #define SMPU9_MASTER_CONFIG COMMON_SMPU_MASTER_CONFIG
230 
231 /* SMPU requires base address aligned to size */
232 #if SMPU9_BASE % REGIONSIZE_TO_BYTES(SMPU9_REGIONSIZE)
233 #error "Flash layout has changed - SMPU9 needs updating"
234 #endif
235 
236 #if S_RAM_CODE_SIZE != REGIONSIZE_TO_BYTES(SMPU9_REGIONSIZE)
237 #error "SMPU9_REGIONSIZE is not equal S_RAM_CODE_SIZE"
238 #endif
239 
240 /* SMPU9 should be contained within SMPU8 */
241 #if SMPU9_BASE < SMPU8_BASE
242 #error "SMPU9 is below SMPU8"
243 #endif
244 
245 #if (SMPU9_BASE + REGIONSIZE_TO_BYTES(SMPU9_REGIONSIZE)) > \
246     (SMPU8_BASE + REGIONSIZE_TO_BYTES(SMPU8_REGIONSIZE))
247 #error "SMPU9 is not within SMPU8"
248 #endif
249 
250 #endif /* __SMPU_CONFIG_H__ */
251