xref: /rk3399_ARM-atf/plat/st/stm32mp1/stm32mp1_shared_resources.c (revision a2150c33edf50a41e99df76eab6eeab9fd9b9215)
1 /*
2  * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdint.h>
9 
10 #include <platform_def.h>
11 
12 #include <common/debug.h>
13 #include <drivers/st/etzpc.h>
14 #include <drivers/st/stm32_gpio.h>
15 
16 #include <stm32mp_shared_resources.h>
17 
18 /*
19  * Once one starts to get the resource registering state, one cannot register
20  * new resources. This ensures resource state cannot change.
21  */
22 static bool registering_locked;
23 
24 /*
25  * Shared peripherals and resources registration
26  *
27  * Each resource assignation is stored in a table. The state defaults
28  * to PERIPH_UNREGISTERED if the resource is not explicitly assigned.
29  *
30  * Resource driver that as not embedded (a.k.a their related CFG_xxx build
31  * directive is disabled) are assigned to the non-secure world.
32  *
33  * Each pin of the GPIOZ bank can be secure or non-secure.
34  *
35  * It is the platform responsibility the ensure resource assignation
36  * matches the access permission firewalls configuration.
37  */
38 enum shres_state {
39 	SHRES_UNREGISTERED = 0,
40 	SHRES_SECURE,
41 	SHRES_NON_SECURE,
42 };
43 
44 /* Force uint8_t array for array of enum shres_state for size considerations */
45 static uint8_t shres_state[STM32MP1_SHRES_COUNT];
46 
47 static const char *shres2str_id_tbl[STM32MP1_SHRES_COUNT] __unused = {
48 	[STM32MP1_SHRES_GPIOZ(0)] = "GPIOZ0",
49 	[STM32MP1_SHRES_GPIOZ(1)] = "GPIOZ1",
50 	[STM32MP1_SHRES_GPIOZ(2)] = "GPIOZ2",
51 	[STM32MP1_SHRES_GPIOZ(3)] = "GPIOZ3",
52 	[STM32MP1_SHRES_GPIOZ(4)] = "GPIOZ4",
53 	[STM32MP1_SHRES_GPIOZ(5)] = "GPIOZ5",
54 	[STM32MP1_SHRES_GPIOZ(6)] = "GPIOZ6",
55 	[STM32MP1_SHRES_GPIOZ(7)] = "GPIOZ7",
56 	[STM32MP1_SHRES_IWDG1] = "IWDG1",
57 	[STM32MP1_SHRES_USART1] = "USART1",
58 	[STM32MP1_SHRES_SPI6] = "SPI6",
59 	[STM32MP1_SHRES_I2C4] = "I2C4",
60 	[STM32MP1_SHRES_RNG1] = "RNG1",
61 	[STM32MP1_SHRES_HASH1] = "HASH1",
62 	[STM32MP1_SHRES_CRYP1] = "CRYP1",
63 	[STM32MP1_SHRES_I2C6] = "I2C6",
64 	[STM32MP1_SHRES_RTC] = "RTC",
65 	[STM32MP1_SHRES_MCU] = "MCU",
66 	[STM32MP1_SHRES_MDMA] = "MDMA",
67 	[STM32MP1_SHRES_PLL3] = "PLL3",
68 };
69 
70 static const char __unused *shres2str_id(enum stm32mp_shres id)
71 {
72 	assert(id < ARRAY_SIZE(shres2str_id_tbl));
73 
74 	return shres2str_id_tbl[id];
75 }
76 
77 static const char __unused *shres2str_state_tbl[] = {
78 	[SHRES_UNREGISTERED] = "unregistered",
79 	[SHRES_NON_SECURE] = "non-secure",
80 	[SHRES_SECURE] = "secure",
81 };
82 
83 static const char __unused *shres2str_state(unsigned int state)
84 {
85 	assert(state < ARRAY_SIZE(shres2str_state_tbl));
86 
87 	return shres2str_state_tbl[state];
88 }
89 
90 /* Get resource state: these accesses lock the registering support */
91 static void lock_registering(void)
92 {
93 	registering_locked = true;
94 }
95 
96 static bool periph_is_non_secure(enum stm32mp_shres id)
97 {
98 	lock_registering();
99 
100 	return (shres_state[id] == SHRES_NON_SECURE) ||
101 	       (shres_state[id] == SHRES_UNREGISTERED);
102 }
103 
104 static bool periph_is_secure(enum stm32mp_shres id)
105 {
106 	return !periph_is_non_secure(id);
107 }
108 
109 /* GPIOZ pin count is saved in RAM to prevent parsing FDT several times */
110 static int8_t gpioz_nbpin = -1;
111 
112 static unsigned int get_gpio_nbpin(unsigned int bank)
113 {
114 	if (bank != GPIO_BANK_Z) {
115 		int count = fdt_get_gpio_bank_pin_count(bank);
116 
117 		assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1)));
118 
119 		return (unsigned int)count;
120 	}
121 
122 	if (gpioz_nbpin < 0) {
123 		int count = fdt_get_gpio_bank_pin_count(GPIO_BANK_Z);
124 
125 		assert((count == 0) || (count == STM32MP_GPIOZ_PIN_MAX_COUNT));
126 
127 		gpioz_nbpin = count;
128 	}
129 
130 	return (unsigned int)gpioz_nbpin;
131 }
132 
133 static unsigned int get_gpioz_nbpin(void)
134 {
135 	return get_gpio_nbpin(GPIO_BANK_Z);
136 }
137 
138 /* Currently allow full access by non-secure to platform clock services */
139 bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
140 {
141 	return true;
142 }
143 
144 /* Currently allow full access by non-secure to platform reset services */
145 bool stm32mp_nsec_can_access_reset(unsigned int reset_id)
146 {
147 	return true;
148 }
149 
150 static bool mckprot_protects_periph(enum stm32mp_shres id)
151 {
152 	switch (id) {
153 	case STM32MP1_SHRES_MCU:
154 	case STM32MP1_SHRES_PLL3:
155 		return true;
156 	default:
157 		return false;
158 	}
159 }
160 
161 /* ETZPC configuration at drivers initialization completion */
162 static enum etzpc_decprot_attributes shres2decprot_attr(enum stm32mp_shres id)
163 {
164 	assert((id < STM32MP1_SHRES_GPIOZ(0)) ||
165 	       (id > STM32MP1_SHRES_GPIOZ(7)));
166 
167 	if (periph_is_non_secure(id)) {
168 		return ETZPC_DECPROT_NS_RW;
169 	}
170 
171 	return ETZPC_DECPROT_S_RW;
172 }
173 
174 static void set_etzpc_secure_configuration(void)
175 {
176 	/* Some system peripherals shall be secure */
177 	etzpc_configure_decprot(STM32MP1_ETZPC_STGENC_ID, ETZPC_DECPROT_S_RW);
178 	etzpc_configure_decprot(STM32MP1_ETZPC_BKPSRAM_ID, ETZPC_DECPROT_S_RW);
179 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRCTRL_ID,
180 				ETZPC_DECPROT_NS_R_S_W);
181 	etzpc_configure_decprot(STM32MP1_ETZPC_DDRPHYC_ID,
182 				ETZPC_DECPROT_NS_R_S_W);
183 
184 	/* Configure ETZPC with peripheral registering */
185 	etzpc_configure_decprot(STM32MP1_ETZPC_CRYP1_ID,
186 				shres2decprot_attr(STM32MP1_SHRES_CRYP1));
187 	etzpc_configure_decprot(STM32MP1_ETZPC_HASH1_ID,
188 				shres2decprot_attr(STM32MP1_SHRES_HASH1));
189 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C4_ID,
190 				shres2decprot_attr(STM32MP1_SHRES_I2C4));
191 	etzpc_configure_decprot(STM32MP1_ETZPC_I2C6_ID,
192 				shres2decprot_attr(STM32MP1_SHRES_I2C6));
193 	etzpc_configure_decprot(STM32MP1_ETZPC_IWDG1_ID,
194 				shres2decprot_attr(STM32MP1_SHRES_IWDG1));
195 	etzpc_configure_decprot(STM32MP1_ETZPC_RNG1_ID,
196 				shres2decprot_attr(STM32MP1_SHRES_RNG1));
197 	etzpc_configure_decprot(STM32MP1_ETZPC_USART1_ID,
198 				shres2decprot_attr(STM32MP1_SHRES_USART1));
199 	etzpc_configure_decprot(STM32MP1_ETZPC_SPI6_ID,
200 				shres2decprot_attr(STM32MP1_SHRES_SPI6));
201 }
202 
203 static void check_rcc_secure_configuration(void)
204 {
205 	uint32_t n;
206 	uint32_t error = 0U;
207 	bool mckprot = stm32mp1_rcc_is_mckprot();
208 	bool secure = stm32mp1_rcc_is_secure();
209 
210 	for (n = 0U; n < ARRAY_SIZE(shres_state); n++) {
211 		if (shres_state[n] != SHRES_SECURE) {
212 			continue;
213 		}
214 
215 		if (!secure || (mckprot_protects_periph(n) && (!mckprot))) {
216 			ERROR("RCC %s MCKPROT %s and %s secure\n",
217 			      secure ? "secure" : "non-secure",
218 			      mckprot ? "set" : "not set",
219 			      shres2str_id(n));
220 			error++;
221 		}
222 	}
223 
224 	if (error != 0U) {
225 		panic();
226 	}
227 }
228 
229 static void set_gpio_secure_configuration(void)
230 {
231 	uint32_t pin;
232 
233 	for (pin = 0U; pin < get_gpioz_nbpin(); pin++) {
234 		bool secure_state = periph_is_secure(STM32MP1_SHRES_GPIOZ(pin));
235 
236 		set_gpio_secure_cfg(GPIO_BANK_Z, pin, secure_state);
237 	}
238 }
239 
240 static void print_shared_resources_state(void)
241 {
242 	unsigned int id;
243 
244 	for (id = 0U; id < STM32MP1_SHRES_COUNT; id++) {
245 		switch (shres_state[id]) {
246 		case SHRES_SECURE:
247 			INFO("stm32mp1 %s is secure\n", shres2str_id(id));
248 			break;
249 		case SHRES_NON_SECURE:
250 		case SHRES_UNREGISTERED:
251 			VERBOSE("stm32mp %s is non-secure\n", shres2str_id(id));
252 			break;
253 		default:
254 			VERBOSE("stm32mp %s is invalid\n", shres2str_id(id));
255 			panic();
256 		}
257 	}
258 }
259 
260 void stm32mp_lock_periph_registering(void)
261 {
262 	registering_locked = true;
263 
264 	print_shared_resources_state();
265 
266 	check_rcc_secure_configuration();
267 	set_etzpc_secure_configuration();
268 	set_gpio_secure_configuration();
269 }
270