stm32mp1: shared resources: peripheral registering
Define helper functions stm32mp_register_secure_periph() and
stm32mp_register_non_secure_periph() for platform drivers to
register a shared resource assigned to respectively secure
or non-secure world.
Some resources are related to clock resources. When a resource is
registered as secure, ensure its clock dependencies are also
registered as secure. Registering a non-secure resource does not
mandate its clock dependencies are also registered as non-secure.
Change-Id: I74975be8976b8d3bf18dcc807541a072803af6e3
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
diff --git a/plat/st/common/include/stm32mp_shared_resources.h b/plat/st/common/include/stm32mp_shared_resources.h
index b148666..2205936 100644
--- a/plat/st/common/include/stm32mp_shared_resources.h
+++ b/plat/st/common/include/stm32mp_shared_resources.h
@@ -9,13 +9,22 @@
#include <stdbool.h>
+#ifdef STM32MP_SHARED_RESOURCES
+enum stm32mp_shres;
+
/* Return true if @clock_id is shared by secure and non-secure worlds */
bool stm32mp_nsec_can_access_clock(unsigned long clock_id);
/* Return true if and only if @reset_id relates to a non-secure peripheral */
bool stm32mp_nsec_can_access_reset(unsigned int reset_id);
+/* Register a shared resource assigned to the secure world */
+void stm32mp_register_secure_periph(enum stm32mp_shres id);
+
+/* Register a shared resource assigned to the non-secure world */
+void stm32mp_register_non_secure_periph(enum stm32mp_shres id);
+
/* Consolidate peripheral states and lock against new peripheral registering */
void stm32mp_lock_periph_registering(void);
-
+#endif /* STM32MP_SHARED_RESOURCES */
#endif /* STM32MP_SHARED_RESOURCES_H */
diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c
index d4ab39d..158393b 100644
--- a/plat/st/stm32mp1/stm32mp1_shared_resources.c
+++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c
@@ -135,6 +135,104 @@
return get_gpio_nbpin(GPIO_BANK_Z);
}
+static void register_periph(enum stm32mp_shres id, unsigned int state)
+{
+ assert((id < STM32MP1_SHRES_COUNT) &&
+ ((state == SHRES_SECURE) || (state == SHRES_NON_SECURE)));
+
+ if (registering_locked) {
+ if (shres_state[id] == state) {
+ return;
+ }
+ panic();
+ }
+
+ if ((shres_state[id] != SHRES_UNREGISTERED) &&
+ (shres_state[id] != state)) {
+ VERBOSE("Cannot change %s from %s to %s\n",
+ shres2str_id(id),
+ shres2str_state(shres_state[id]),
+ shres2str_state(state));
+ panic();
+ }
+
+ if (shres_state[id] == SHRES_UNREGISTERED) {
+ VERBOSE("Register %s as %s\n",
+ shres2str_id(id), shres2str_state(state));
+ }
+
+ if ((id >= STM32MP1_SHRES_GPIOZ(0)) &&
+ (id <= STM32MP1_SHRES_GPIOZ(7)) &&
+ ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) {
+ ERROR("Invalid GPIO pin %u, %u pin(s) available\n",
+ id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin());
+ panic();
+ }
+
+ shres_state[id] = (uint8_t)state;
+
+ /* Explore clock tree to lock dependencies */
+ if (state == SHRES_SECURE) {
+ enum stm32mp_shres clock_res_id;
+
+ switch (id) {
+ case STM32MP1_SHRES_GPIOZ(0):
+ case STM32MP1_SHRES_GPIOZ(1):
+ case STM32MP1_SHRES_GPIOZ(2):
+ case STM32MP1_SHRES_GPIOZ(3):
+ case STM32MP1_SHRES_GPIOZ(4):
+ case STM32MP1_SHRES_GPIOZ(5):
+ case STM32MP1_SHRES_GPIOZ(6):
+ case STM32MP1_SHRES_GPIOZ(7):
+ clock_res_id = GPIOZ;
+ break;
+ case STM32MP1_SHRES_IWDG1:
+ clock_res_id = IWDG1;
+ break;
+ case STM32MP1_SHRES_USART1:
+ clock_res_id = USART1_K;
+ break;
+ case STM32MP1_SHRES_SPI6:
+ clock_res_id = SPI6_K;
+ break;
+ case STM32MP1_SHRES_I2C4:
+ clock_res_id = I2C4_K;
+ break;
+ case STM32MP1_SHRES_RNG1:
+ clock_res_id = RNG1_K;
+ break;
+ case STM32MP1_SHRES_HASH1:
+ clock_res_id = HASH1;
+ break;
+ case STM32MP1_SHRES_CRYP1:
+ clock_res_id = CRYP1;
+ break;
+ case STM32MP1_SHRES_I2C6:
+ clock_res_id = I2C6_K;
+ break;
+ case STM32MP1_SHRES_RTC:
+ clock_res_id = RTC;
+ break;
+ default:
+ /* No clock resource dependency */
+ return;
+ }
+
+ stm32mp1_register_clock_parents_secure(clock_res_id);
+ }
+}
+
+/* Register resource by ID */
+void stm32mp_register_secure_periph(enum stm32mp_shres id)
+{
+ register_periph(id, SHRES_SECURE);
+}
+
+void stm32mp_register_non_secure_periph(enum stm32mp_shres id)
+{
+ register_periph(id, SHRES_NON_SECURE);
+}
+
/* Currently allow full access by non-secure to platform clock services */
bool stm32mp_nsec_can_access_clock(unsigned long clock_id)
{