1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4 *
5 */
6
7 #include "tfm_hal_device_header.h"
8 #include "region_defs.h"
9 #include "target_cfg.h"
10 #include "tfm_plat_defs.h"
11 #include "tfm_peripherals_def.h"
12 #include "hardware/uart.h"
13 #include "region.h"
14 #include "hardware/regs/addressmap.h"
15 #include "hardware/structs/accessctrl.h"
16 #include "hardware/structs/dma.h"
17
18 #define REG_RW(addr) (*(volatile uint32_t *)(addr))
19
20 #define ACCESSCTRL_DBG (1U << 7)
21 #define ACCESSCTRL_DMA (1U << 6)
22 #define ACCESSCTRL_CORE1 (1U << 5)
23 #define ACCESSCTRL_CORE0 (1U << 4)
24 #define ACCESSCTRL_SP (1U << 3)
25 #define ACCESSCTRL_SU (1U << 2)
26 #define ACCESSCTRL_NSP (1U << 1)
27 #define ACCESSCTRL_NSU (1U << 0)
28
29 #define ACCESSCTRL_NS_PRIV (ACCESSCTRL_DBG | ACCESSCTRL_DMA | \
30 ACCESSCTRL_CORE1 | ACCESSCTRL_CORE0 |\
31 ACCESSCTRL_SP | ACCESSCTRL_SU | \
32 ACCESSCTRL_NSP)
33 #define ACCESSCTRL_S_UNPRIV_C0 (ACCESSCTRL_DBG | ACCESSCTRL_CORE0 |\
34 ACCESSCTRL_SP | ACCESSCTRL_SU)
35 /* Only grant access to Core0 when Multi-core topology is not in use */
36 #ifdef TFM_MULTI_CORE_TOPOLOGY
37 #define ACCESSCTRL_S_UNPRIV_C0_C1 (ACCESSCTRL_DBG | ACCESSCTRL_CORE0 |\
38 ACCESSCTRL_CORE1 | ACCESSCTRL_SP |\
39 ACCESSCTRL_SU)
40 #else
41 #define ACCESSCTRL_S_UNPRIV_C0_C1 ACCESSCTRL_S_UNPRIV_C0
42 #endif
43 #define ACCESSCTRL_S_PRIV_C0 (ACCESSCTRL_DBG | ACCESSCTRL_CORE0 |\
44 ACCESSCTRL_SP)
45
46
47 #ifdef CONFIG_TFM_USE_TRUSTZONE
48 REGION_DECLARE(Image$$, ER_VENEER, $$Base);
49 REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
50 #endif /* CONFIG_TFM_USE_TRUSTZONE */
51 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE_START, $$RO$$Base);
52 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE_END, $$RO$$Limit);
53 REGION_DECLARE(Image$$, TFM_APP_CODE_START, $$Base);
54 REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base);
55 REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base);
56 REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base);
57 #ifdef CONFIG_TFM_PARTITION_META
58 REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Base);
59 REGION_DECLARE(Image$$, TFM_SP_META_PTR_END, $$ZI$$Limit);
60 #endif /* CONFIG_TFM_PARTITION_META */
61
62 #define FF_TEST_NVMEM_REGION_START 0x2005E000
63 #define FF_TEST_NVMEM_REGION_END 0x2005E3FF
64 #define FF_TEST_SERVER_PARTITION_MMIO_START 0x2005E400
65 #define FF_TEST_SERVER_PARTITION_MMIO_END 0x2005E4FF
66 #define FF_TEST_DRIVER_PARTITION_MMIO_START 0x2005E600
67 #define FF_TEST_DRIVER_PARTITION_MMIO_END 0x2005E6FF
68
69 extern const struct memory_region_limits memory_regions;
70
71 struct platform_data_t tfm_peripheral_std_uart = {
72 .periph_start = UART0_BASE,
73 .periph_limit = UART0_BASE + 0x3FFF,
74 /* Based on platform_data_t definition TF-M expects PPC to control
75 security and privilege settings. There is no PPC on this platform.
76 Using periph_ppc_mask to store accessctrl register index. */
77 .periph_ppc_mask = AC_DO_NOT_CONFIGURE,
78 };
79
80 struct platform_data_t tfm_peripheral_timer0 = {
81 .periph_start = TIMER0_BASE,
82 .periph_limit = TIMER0_BASE + 0x3FFF,
83 /* Based on platform_data_t definition TF-M expects PPC to control
84 security and privilege settings. There is no PPC on this platform.
85 Using periph_ppc_mask to store accessctrl register index. */
86 .periph_ppc_mask = AC_TIMER0,
87 };
88
89 #ifdef PSA_API_TEST_IPC
90
91 /* Below data structure are only used for PSA FF tests, and this pattern is
92 * definitely not to be followed for real life use cases, as it can break
93 * security.
94 */
95
96 struct platform_data_t
97 tfm_peripheral_FF_TEST_UART_REGION = {
98 .periph_start = UART1_BASE,
99 .periph_limit = UART1_BASE + 0x3FFF,
100 .periph_ppc_mask = AC_UART1,
101 };
102
103 struct platform_data_t
104 tfm_peripheral_FF_TEST_WATCHDOG_REGION = {
105 .periph_start = WATCHDOG_BASE,
106 .periph_limit = WATCHDOG_BASE + 0x3FFF,
107 .periph_ppc_mask = AC_DO_NOT_CONFIGURE,
108 };
109
110 struct platform_data_t
111 tfm_peripheral_FF_TEST_NVMEM_REGION = {
112 .periph_start = FF_TEST_NVMEM_REGION_START,
113 .periph_limit = FF_TEST_NVMEM_REGION_END,
114 .periph_ppc_mask = AC_DO_NOT_CONFIGURE
115 };
116
117 struct platform_data_t
118 tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO = {
119 .periph_start = FF_TEST_SERVER_PARTITION_MMIO_START,
120 .periph_limit = FF_TEST_SERVER_PARTITION_MMIO_END,
121 .periph_ppc_mask = AC_DO_NOT_CONFIGURE
122 };
123
124 struct platform_data_t
125 tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO = {
126 .periph_start = FF_TEST_DRIVER_PARTITION_MMIO_START,
127 .periph_limit = FF_TEST_DRIVER_PARTITION_MMIO_END,
128 .periph_ppc_mask = AC_DO_NOT_CONFIGURE
129 };
130 #endif
131
132 /*------------------- SAU/IDAU configuration functions -----------------------*/
sau_and_idau_cfg(void)133 void sau_and_idau_cfg(void)
134 {
135 /* Ensure all memory accesses are completed */
136 __DMB();
137 #if 0 /* Bootrom set to be secure temporary */
138 /* Configures SAU regions to be non-secure */
139 /* Configure Bootrom */
140 SAU->RNR = 0;
141 SAU->RBAR = (ROM_BASE & SAU_RBAR_BADDR_Msk);
142 SAU->RLAR = ((ROM_BASE + 0x7E00 - 1) & SAU_RLAR_LADDR_Msk)
143 | SAU_RLAR_ENABLE_Msk;
144
145 /* Configure Bootrom SGs */
146 SAU->RNR = 1;
147 SAU->RBAR = ((ROM_BASE + 0x7E00) & SAU_RBAR_BADDR_Msk);
148 SAU->RLAR = ((ROM_BASE + 0x7FFF) & SAU_RLAR_LADDR_Msk)
149 | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk;
150 #endif
151
152 /* Configures veneers region to be non-secure callable */
153 SAU->RNR = 2;
154 SAU->RBAR = (memory_regions.veneer_base & SAU_RBAR_BADDR_Msk);
155 SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
156 | SAU_RLAR_ENABLE_Msk | SAU_RLAR_NSC_Msk;
157
158 /* Configure Non-Secure partition in flash */
159 SAU->RNR = 3;
160 SAU->RBAR = (memory_regions.non_secure_partition_base
161 & SAU_RBAR_BADDR_Msk);
162 SAU->RLAR = (memory_regions.non_secure_partition_limit
163 & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
164
165 /* Configure the rest of the address map up to PPB */
166 SAU->RNR = 4;
167 SAU->RBAR = (SRAM4_BASE & SAU_RBAR_BADDR_Msk);
168 SAU->RLAR = ((PPB_BASE - 1) & SAU_RLAR_LADDR_Msk)
169 | SAU_RLAR_ENABLE_Msk;
170
171 /* Turn off unused bootrom region */
172 SAU->RNR = 7;
173 SAU->RBAR = 0;
174 SAU->RLAR = 0;
175
176 /* Enables SAU */
177 TZ_SAU_Enable();
178 /* Add barriers to assure the SAU configuration is done before continue
179 * the execution.
180 */
181 __DSB();
182 __ISB();
183 }
184
bus_filter_cfg(void)185 enum tfm_plat_err_t bus_filter_cfg(void)
186 {
187 enum tfm_plat_err_t err = TFM_PLAT_ERR_SUCCESS;
188 uint32_t c0_c1_unpriv_periph_offsets[] = {AC_SRAM0,
189 AC_SRAM1, AC_SRAM2, AC_SRAM3};
190 uint8_t nbr_of_c0_c1_unpriv_periphs;
191 uint32_t c0_unpriv_periph_offsets[] = {AC_SYSCFG, AC_CLOCKS_BANK_DEFAULT,
192 AC_RSM, AC_BUSCTRL, AC_OTP, AC_POWMAN, AC_TRNG, AC_XOSC,
193 AC_ROSC, AC_PLL_SYS, AC_PLL_USB, AC_TICKS, AC_XIP_CTRL,
194 AC_XIP_QMI};
195 uint8_t nbr_of_c0_unpriv_periphs;
196 uint32_t ns_priv_periph_offsets[] = {AC_ROM, AC_XIP_MAIN, AC_SRAM4,
197 AC_SRAM5, AC_SRAM6, AC_SRAM7, AC_SRAM8, AC_SRAM9, AC_DMA,
198 AC_USBCTRL, AC_PIO0, AC_PIO1, AC_PIO2, AC_CORESIGHT_TRACE,
199 AC_CORESIGHT_PERIPH, AC_SYSINFO, AC_RESETS, AC_IO_BANK0,
200 AC_IO_BANK1, AC_PADS_BANK0, AC_PADS_QSPI, AC_ADC0, AC_HSTX,
201 AC_I2C0, AC_I2C1, AC_PWM, AC_SPI0, AC_SPI1, AC_TIMER0,
202 AC_TIMER1, AC_UART0, AC_UART1, AC_TBMAN, AC_SHA256, AC_WATCHDOG,
203 AC_XIP_AUX};
204 uint8_t nbr_of_ns_periphs;
205 uint32_t temp_addr;
206
207 nbr_of_c0_c1_unpriv_periphs = sizeof(c0_c1_unpriv_periph_offsets) /
208 sizeof(c0_c1_unpriv_periph_offsets[0]);
209 nbr_of_c0_unpriv_periphs = sizeof(c0_unpriv_periph_offsets) /
210 sizeof(c0_unpriv_periph_offsets[0]);
211 nbr_of_ns_periphs = sizeof(ns_priv_periph_offsets) /
212 sizeof(ns_priv_periph_offsets[0]);
213
214 /* Probably worth doing a software reset of access ctrl before setup */
215 accessctrl_hw->cfgreset = ACCESSCTRL_PASSWORD_BITS | 0x1;
216
217 accessctrl_hw->gpio_nsmask[0] = 0xFFFFFFFC;
218 accessctrl_hw->gpio_nsmask[1] = 0xFF00FFFF;
219
220 /* Peripherals controlled by Secure Core0 and Core1 */
221 for (uint8_t i = 0; i < nbr_of_c0_c1_unpriv_periphs; i++){
222 temp_addr = ACCESSCTRL_BASE + c0_c1_unpriv_periph_offsets[i];
223 REG_RW(temp_addr) = ACCESSCTRL_S_UNPRIV_C0_C1 |
224 ACCESSCTRL_PASSWORD_BITS;
225 if (REG_RW(temp_addr) != ACCESSCTRL_S_UNPRIV_C0_C1) {
226 err = TFM_PLAT_ERR_SYSTEM_ERR;
227 }
228 }
229
230 /* Peripherals controlled by Secure Core0 */
231 for (uint8_t i = 0; i < nbr_of_c0_unpriv_periphs; i++){
232 temp_addr = ACCESSCTRL_BASE + c0_unpriv_periph_offsets[i];
233 REG_RW(temp_addr) = ACCESSCTRL_S_UNPRIV_C0 |
234 ACCESSCTRL_PASSWORD_BITS;
235 if (REG_RW(temp_addr) != ACCESSCTRL_S_UNPRIV_C0) {
236 err = TFM_PLAT_ERR_SYSTEM_ERR;
237 }
238 }
239
240 /* Peripherals accessable to all bus actors */
241 for (uint8_t i = 0; i < nbr_of_ns_periphs; i++){
242 temp_addr = ACCESSCTRL_BASE + ns_priv_periph_offsets[i];
243 REG_RW(temp_addr) = ACCESSCTRL_NS_PRIV |
244 ACCESSCTRL_PASSWORD_BITS;
245 if (REG_RW(temp_addr) != ACCESSCTRL_NS_PRIV) {
246 err = TFM_PLAT_ERR_SYSTEM_ERR;
247 }
248 }
249
250 /* Lock setings for every actor except Core0, only hard reset can clear
251 this. Core0 must retain control for mmio control. */
252 accessctrl_hw->lock = ACCESSCTRL_PASSWORD_BITS | 0x6;
253
254 return err;
255 }
256
access_ctrl_configure_to_secure_privileged(access_ctrl_reg_offset offset)257 void access_ctrl_configure_to_secure_privileged(access_ctrl_reg_offset offset)
258 {
259 if (offset != AC_DO_NOT_CONFIGURE){
260 REG_RW(ACCESSCTRL_BASE + offset) =
261 ACCESSCTRL_S_PRIV_C0 | ACCESSCTRL_PASSWORD_BITS;
262 }
263 }
264
access_ctrl_configure_to_secure_unprivileged(access_ctrl_reg_offset offset)265 void access_ctrl_configure_to_secure_unprivileged(access_ctrl_reg_offset offset)
266 {
267 if (offset != AC_DO_NOT_CONFIGURE){
268 REG_RW(ACCESSCTRL_BASE + offset) =
269 ACCESSCTRL_S_UNPRIV_C0 | ACCESSCTRL_PASSWORD_BITS;
270 }
271 }
272
dma_security_config(void)273 enum tfm_plat_err_t dma_security_config(void)
274 {
275 /* Configure every DMA channel as Nonsecure Privileged since TF-M uses no DMA */
276 for (int i=0; i<16; i++){
277 REG_RW(DMA_BASE + DMA_SECCFG_CH0_OFFSET + (i * 4)) =
278 DMA_SECCFG_CH0_P_BITS;
279 }
280
281 /* Configure DMA MPU to mirror SAU settings */
282 /* Unmapped address regions default to SP */
283 dma_hw->mpu_ctrl = DMA_MPU_CTRL_NS_HIDE_ADDR_BITS | DMA_MPU_CTRL_S_BITS |
284 DMA_MPU_CTRL_P_BITS;
285
286 /* Configure MPU regions */
287 dma_hw->mpu_region[0].bar = (memory_regions.veneer_base &
288 DMA_MPU_BAR0_BITS);
289 dma_hw->mpu_region[0].lar = (memory_regions.veneer_limit &
290 DMA_MPU_LAR0_ADDR_BITS) |
291 DMA_MPU_LAR0_P_BITS | DMA_MPU_LAR0_EN_BITS;
292
293 dma_hw->mpu_region[1].bar = (memory_regions.non_secure_partition_base &
294 DMA_MPU_BAR0_BITS);
295 dma_hw->mpu_region[1].lar = (memory_regions.veneer_limit &
296 DMA_MPU_LAR0_ADDR_BITS) |
297 DMA_MPU_LAR0_P_BITS | DMA_MPU_LAR0_EN_BITS;
298
299 dma_hw->mpu_region[2].bar = (SRAM4_BASE & DMA_MPU_BAR0_BITS);
300 dma_hw->mpu_region[2].lar = ((PPB_BASE - 1) & DMA_MPU_LAR0_ADDR_BITS) |
301 DMA_MPU_LAR0_P_BITS | DMA_MPU_LAR0_EN_BITS;
302
303 dma_hw->mpu_region[3].bar = 0;
304 dma_hw->mpu_region[3].lar = 0;
305
306 dma_hw->mpu_region[4].bar = 0;
307 dma_hw->mpu_region[4].lar = 0;
308
309 dma_hw->mpu_region[5].bar = 0;
310 dma_hw->mpu_region[5].lar = 0;
311
312 dma_hw->mpu_region[6].bar = 0;
313 dma_hw->mpu_region[6].lar = 0;
314
315 dma_hw->mpu_region[7].bar = 0;
316 dma_hw->mpu_region[7].lar = 0;
317
318 return TFM_PLAT_ERR_SUCCESS;
319 }
320
321