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