1 /*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "bootutil/bootutil_log.h"
8 #include "host_device_definition.h"
9 #include "host_base_address.h"
10 #include "ni_tower_lib.h"
11
12 #include <stddef.h>
13
14 #define RAM_AXIS_RO_APU_REGION_IDX (0)
15 #define RAM_AXIS_RW_APU_REGION_IDX (1)
16
17 /* Peripheral NI-Tower component nodes */
18 const struct ni_tower_component_node periph_ram_amni = {
19 .type = NI_TOWER_AMNI,
20 .id = PERIPH_RAM_AMNI_ID,
21 };
22
23 const struct ni_tower_component_node periph_nsuart0_pmni = {
24 .type = NI_TOWER_PMNI,
25 .id = PERIPH_NSUART0_PMNI_ID,
26 };
27
28 const struct ni_tower_component_node periph_secuart_pmni = {
29 .type = NI_TOWER_PMNI,
30 .id = PERIPH_SECUART_PMNI_ID,
31 };
32
33 const struct ni_tower_component_node periph_nsuart1_pmni = {
34 .type = NI_TOWER_PMNI,
35 .id = PERIPH_NSUART1_PMNI_ID,
36 };
37
38 const struct ni_tower_component_node periph_nsgenwdog_pmni = {
39 .type = NI_TOWER_PMNI,
40 .id = PERIPH_NSGENWDOG_PMNI_ID,
41 };
42
43 const struct ni_tower_component_node periph_rootgenwdog_pmni = {
44 .type = NI_TOWER_PMNI,
45 .id = PERIPH_ROOTGENWDOG_PMNI_ID,
46 };
47
48 const struct ni_tower_component_node periph_secgenwdog_pmni = {
49 .type = NI_TOWER_PMNI,
50 .id = PERIPH_SECGENWDOG_PMNI_ID,
51 };
52
53 const struct ni_tower_component_node PERIPH_ECCREG_PMNI_APU_DEV_CFG = {
54 .type = NI_TOWER_PMNI,
55 .id = PERIPH_ECCREG_PMNI_ID,
56 };
57
58 const struct ni_tower_component_node periph_gtimerctrl_pmni = {
59 .type = NI_TOWER_PMNI,
60 .id = PERIPH_GTIMERCTRL_PMNI_ID,
61 };
62
63 const struct ni_tower_component_node periph_secgtimer_pmni = {
64 .type = NI_TOWER_PMNI,
65 .id = PERIPH_SECGTIMER_PMNI_ID,
66 };
67
68 const struct ni_tower_component_node periph_nsgtimer_pmni = {
69 .type = NI_TOWER_PMNI,
70 .id = PERIPH_NSGTIMER_PMNI_ID,
71 };
72
73 /*
74 * Software implementation defined region for SRAM and is accessible by AP,
75 * RSE, SCP and MCP. First region (AP BL1 code region) will be changed to Read
76 * only access after RSE loads AP BL1 image.
77 */
78 static const struct ni_tower_apu_reg_cfg_info ram_axim_apu[] = {
79 [RAM_AXIS_RO_APU_REGION_IDX] =
80 INIT_APU_REGION_UNLOCKED(
81 HOST_AP_BL1_RO_SRAM_PHYS_BASE,
82 HOST_AP_BL1_RO_SRAM_PHYS_LIMIT,
83 NI_T_ROOT_RW),
84 [RAM_AXIS_RW_APU_REGION_IDX] =
85 INIT_APU_REGION(HOST_AP_BL1_RW_SRAM_PHYS_BASE,
86 HOST_AP_BL1_RW_SRAM_PHYS_LIMIT,
87 NI_T_ROOT_RW),
88 };
89
90 /* AP Non-secure UART */
91 static const struct ni_tower_apu_reg_cfg_info nsuart0_apbm_apu[] = {
92 INIT_APU_REGION(HOST_NS_UART_PHYS_BASE,
93 HOST_NS_UART_PHYS_LIMIT,
94 NI_T_ALL_PERM),
95 };
96
97 /* AP Secure UART */
98 static const struct ni_tower_apu_reg_cfg_info secuart_apbm_apu[] = {
99 INIT_APU_REGION(HOST_S_UART_PHYS_BASE,
100 HOST_S_UART_PHYS_LIMIT,
101 NI_T_ROOT_RW | NI_T_SEC_RW),
102 };
103
104 /* AP Non-secure UART for RMM debug */
105 static const struct ni_tower_apu_reg_cfg_info nsuart1_apbm_apu[] = {
106 INIT_APU_REGION(HOST_RMM_NS_UART_PHYS_BASE,
107 HOST_RMM_NS_UART_PHYS_LIMIT,
108 NI_T_REALM_RW),
109 };
110
111 /* AP Non-secure WatchDog */
112 static const struct ni_tower_apu_reg_cfg_info nsgenwdog_apbm_apu[] = {
113 INIT_APU_REGION(HOST_AP_NS_WDOG_PHYS_BASE,
114 HOST_AP_NS_WDOG_PHYS_LIMIT,
115 NI_T_ALL_PERM),
116 };
117
118 /* AP root WatchDog */
119 static const struct ni_tower_apu_reg_cfg_info rootgenwdog_apbm_apu[] = {
120 INIT_APU_REGION(HOST_AP_RT_WDOG_PHYS_BASE,
121 HOST_AP_RT_WDOG_PHYS_LIMIT,
122 NI_T_ROOT_RW),
123 };
124
125 /* AP Secure WatchDog */
126 static const struct ni_tower_apu_reg_cfg_info secgenwdog_apbm_apu[] = {
127 INIT_APU_REGION(HOST_AP_S_WDOG_PHYS_BASE,
128 HOST_AP_S_WDOG_PHYS_LIMIT,
129 NI_T_ROOT_RW | NI_T_SEC_RW),
130 };
131
132 /* Secure SRAM Error record block for the shared ARSM SRAM */
133 static const struct ni_tower_apu_reg_cfg_info eccreg_apbm_apu[] = {
134 INIT_APU_REGION(HOST_AP_S_ARSM_RAM_ECC_REC_PHYS_BASE,
135 HOST_AP_S_ARSM_RAM_ECC_REC_PHYS_LIMIT,
136 NI_T_ROOT_RW | NI_T_SEC_RW),
137 INIT_APU_REGION(HOST_AP_NS_ARSM_RAM_ECC_REC_PHYS_BASE,
138 HOST_AP_NS_ARSM_RAM_ECC_REC_PHYS_LIMIT,
139 NI_T_ALL_PERM),
140 INIT_APU_REGION(HOST_AP_RT_ARSM_RAM_ECC_REC_PHYS_BASE,
141 HOST_AP_RT_ARSM_RAM_ECC_REC_PHYS_LIMIT,
142 NI_T_ROOT_RW),
143 INIT_APU_REGION(HOST_AP_RL_ARSM_RAM_ECC_REC_PHYS_BASE,
144 HOST_AP_RL_ARSM_RAM_ECC_REC_PHYS_LIMIT,
145 NI_T_REALM_RW),
146 INIT_APU_REGION(HOST_SCP_S_ARSM_RAM_ECC_REC_PHYS_BASE,
147 HOST_SCP_S_ARSM_RAM_ECC_REC_PHYS_LIMIT,
148 NI_T_ROOT_RW | NI_T_SEC_RW),
149 INIT_APU_REGION(HOST_SCP_NS_ARSM_RAM_ECC_REC_PHYS_BASE,
150 HOST_SCP_NS_ARSM_RAM_ECC_REC_PHYS_LIMIT,
151 NI_T_ALL_PERM),
152 INIT_APU_REGION(HOST_SCP_RT_ARSM_RAM_ECC_REC_PHYS_BASE,
153 HOST_SCP_RT_ARSM_RAM_ECC_REC_PHYS_LIMIT,
154 NI_T_ROOT_RW),
155 INIT_APU_REGION(HOST_SCP_RL_ARSM_RAM_ECC_REC_PHYS_BASE,
156 HOST_SCP_RL_ARSM_RAM_ECC_REC_PHYS_LIMIT,
157 NI_T_REALM_RW),
158 INIT_APU_REGION(HOST_MCP_S_ARSM_RAM_ECC_REC_PHYS_BASE,
159 HOST_MCP_S_ARSM_RAM_ECC_REC_PHYS_LIMIT,
160 NI_T_ROOT_RW | NI_T_SEC_RW),
161 INIT_APU_REGION(HOST_MCP_NS_ARSM_RAM_ECC_REC_PHYS_BASE,
162 HOST_MCP_NS_ARSM_RAM_ECC_REC_PHYS_LIMIT,
163 NI_T_ALL_PERM),
164 INIT_APU_REGION(HOST_MCP_RT_ARSM_RAM_ECC_REC_PHYS_BASE,
165 HOST_MCP_RT_ARSM_RAM_ECC_REC_PHYS_LIMIT,
166 NI_T_ROOT_RW),
167 INIT_APU_REGION(HOST_MCP_RL_ARSM_RAM_ECC_REC_PHYS_BASE,
168 HOST_MCP_RL_ARSM_RAM_ECC_REC_PHYS_LIMIT,
169 NI_T_REALM_RW),
170 INIT_APU_REGION(HOST_RSE_S_ARSM_RAM_ECC_REC_PHYS_BASE,
171 HOST_RSE_S_ARSM_RAM_ECC_REC_PHYS_LIMIT,
172 NI_T_ROOT_RW | NI_T_SEC_RW),
173 INIT_APU_REGION(HOST_RSE_NS_ARSM_RAM_ECC_REC_PHYS_BASE,
174 HOST_RSE_NS_ARSM_RAM_ECC_REC_PHYS_LIMIT,
175 NI_T_ALL_PERM),
176 INIT_APU_REGION(HOST_RSE_RT_ARSM_RAM_ECC_REC_PHYS_BASE,
177 HOST_RSE_RT_ARSM_RAM_ECC_REC_PHYS_LIMIT,
178 NI_T_ROOT_RW),
179 INIT_APU_REGION(HOST_RSE_RL_ARSM_RAM_ECC_REC_PHYS_BASE,
180 HOST_RSE_RL_ARSM_RAM_ECC_REC_PHYS_LIMIT,
181 NI_T_REALM_RW),
182 };
183
184 /* AP Generic Timer Control Frame */
185 static const struct ni_tower_apu_reg_cfg_info gtimerctrl_apbm_apu[] = {
186 INIT_APU_REGION(HOST_AP_REFCLK_CNTCTL_PHYS_BASE,
187 HOST_AP_REFCLK_CNTCTL_PHYS_LIMIT,
188 NI_T_ALL_PERM),
189 };
190
191 /* AP Secure Generic Timer Control Base Frame */
192 static const struct ni_tower_apu_reg_cfg_info secgtimer_apbm_apu[] = {
193 INIT_APU_REGION(HOST_AP_S_REFCLK_CNTBASE0_PHYS_BASE,
194 HOST_AP_S_REFCLK_CNTBASE0_PHYS_LIMIT,
195 NI_T_ROOT_RW | NI_T_SEC_RW),
196 };
197
198 /* AP Non-secure Generic Timer Control Base Frame */
199 static const struct ni_tower_apu_reg_cfg_info nsgtimer_apbm_apu[] = {
200 INIT_APU_REGION(HOST_AP_NS_REFCLK_CNTBASE1_PHYS_BASE,
201 HOST_AP_NS_REFCLK_CNTBASE1_PHYS_LIMIT,
202 NI_T_ALL_PERM),
203 };
204
205 /*
206 * Configure Access Protection Unit (APU) to setup access permission for each
207 * memory region based on its target in Peripheral NI-Tower.
208 */
program_periph_apu(void)209 static int32_t program_periph_apu(void)
210 {
211 enum ni_tower_err err;
212
213 /*
214 * Populates all APU entry into a table array to confgiure and enable
215 * desired APUs
216 */
217 const struct ni_tower_apu_cfgs apu_table[] = {
218 {
219 .component = &periph_ram_amni,
220 .region_count = ARRAY_SIZE(ram_axim_apu),
221 .regions = ram_axim_apu,
222 .add_chip_addr_offset = false,
223 },
224 {
225 .component = &periph_nsuart0_pmni,
226 .region_count = ARRAY_SIZE(nsuart0_apbm_apu),
227 .regions = nsuart0_apbm_apu,
228 .add_chip_addr_offset = false,
229 },
230 {
231 .component = &periph_secuart_pmni,
232 .region_count = ARRAY_SIZE(secuart_apbm_apu),
233 .regions = secuart_apbm_apu,
234 .add_chip_addr_offset = false,
235 },
236 {
237 .component = &periph_nsuart1_pmni,
238 .region_count = ARRAY_SIZE(nsuart1_apbm_apu),
239 .regions = nsuart1_apbm_apu,
240 .add_chip_addr_offset = false,
241 },
242 {
243 .component = &periph_nsgenwdog_pmni,
244 .region_count = ARRAY_SIZE(nsgenwdog_apbm_apu),
245 .regions = nsgenwdog_apbm_apu,
246 .add_chip_addr_offset = false,
247 },
248 {
249 .component = &periph_rootgenwdog_pmni,
250 .region_count = ARRAY_SIZE(rootgenwdog_apbm_apu),
251 .regions = rootgenwdog_apbm_apu,
252 .add_chip_addr_offset = false,
253 },
254 {
255 .component = &periph_secgenwdog_pmni,
256 .region_count = ARRAY_SIZE(secgenwdog_apbm_apu),
257 .regions = secgenwdog_apbm_apu,
258 .add_chip_addr_offset = false,
259 },
260 {
261 .component = &PERIPH_ECCREG_PMNI_APU_DEV_CFG,
262 .region_count = ARRAY_SIZE(eccreg_apbm_apu),
263 .regions = eccreg_apbm_apu,
264 .add_chip_addr_offset = false,
265 },
266 {
267 .component = &periph_gtimerctrl_pmni,
268 .region_count = ARRAY_SIZE(gtimerctrl_apbm_apu),
269 .regions = gtimerctrl_apbm_apu,
270 .add_chip_addr_offset = false,
271 },
272 {
273 .component = &periph_secgtimer_pmni,
274 .region_count = ARRAY_SIZE(secgtimer_apbm_apu),
275 .regions = secgtimer_apbm_apu,
276 .add_chip_addr_offset = false,
277 },
278 {
279 .component = &periph_nsgtimer_pmni,
280 .region_count = ARRAY_SIZE(nsgtimer_apbm_apu),
281 .regions = nsgtimer_apbm_apu,
282 .add_chip_addr_offset = false,
283 },
284 };
285
286 err = ni_tower_program_apu_table(&PERIPH_NI_TOWER_DEV, apu_table,
287 ARRAY_SIZE(apu_table));
288 if (err != NI_TOWER_SUCCESS) {
289 return -1;
290 }
291
292 return 0;
293 }
294
program_periph_ni_tower(void)295 int32_t program_periph_ni_tower(void)
296 {
297 return program_periph_apu();
298 }
299
program_periph_ni_tower_post_ap_bl1_load(void)300 int32_t program_periph_ni_tower_post_ap_bl1_load(void)
301 {
302 enum ni_tower_err err;
303 struct ni_tower_apu_dev apu_dev = {0};
304
305 /* Make AP_BL1_RO region read only access */
306 struct ni_tower_apu_reg_cfg_info ram_axim_region_0 =
307 INIT_APU_REGION(HOST_AP_BL1_RO_SRAM_PHYS_BASE,
308 HOST_AP_BL1_RO_SRAM_PHYS_LIMIT,
309 NI_T_ROOT_R);
310
311 /* Initialize APU device */
312 err = ni_tower_apu_dev_init(&PERIPH_NI_TOWER_DEV,
313 &periph_ram_amni,
314 PERIPH_NI_TOWER_DEV.chip_addr_offset,
315 &apu_dev);
316 if (err != NI_TOWER_SUCCESS) {
317 return -1;
318 }
319
320 if (ni_tower_apu_configure_region(&apu_dev, &ram_axim_region_0,
321 RAM_AXIS_RO_APU_REGION_IDX) !=
322 NI_TOWER_SUCCESS) {
323 return -1;
324 }
325
326 return 0;
327 }
328