From 1f0fed52b65cbae03f972fd286d98bac86eadbc0 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 4 Jul 2024 18:49:59 +0200 Subject: [PATCH 01/20] dt-bindings: gpio: stm32mp: flags for non-secure GPIOs Define STM32 GPIO DT bindings bit flags for GPIOs that are to be used in non-secure state. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/include/dt-bindings/gpio/stm32mp_gpio.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/include/dt-bindings/gpio/stm32mp_gpio.h b/core/include/dt-bindings/gpio/stm32mp_gpio.h index 3afcf415824..7c5ac399fd5 100644 --- a/core/include/dt-bindings/gpio/stm32mp_gpio.h +++ b/core/include/dt-bindings/gpio/stm32mp_gpio.h @@ -15,4 +15,11 @@ #define TZPROT(id) (UINT32_C(1) << (id)) #endif +/* GPIO phandle argument bitmask for a non-secure GPIO */ +#ifdef __ASSEMBLER__ +#define GPIO_STM32_NSEC (1 << 31) +#else +#define GPIO_STM32_NSEC (UINT32_C(1) << 31) +#endif + #endif From c80834b0b22693c5cf507ea7fa9aea7d81a36620 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 17 Sep 2024 10:35:14 +0200 Subject: [PATCH 02/20] dt-bindings: pinctrl: stm32mp: flags for non-secure pins Define stm32 pinctrl DT bindings bit flags for pins that are expected to be used in non-secure state. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/include/dt-bindings/pinctrl/stm32-pinfunc.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/include/dt-bindings/pinctrl/stm32-pinfunc.h b/core/include/dt-bindings/pinctrl/stm32-pinfunc.h index 370a25a9366..afd118f8b5f 100644 --- a/core/include/dt-bindings/pinctrl/stm32-pinfunc.h +++ b/core/include/dt-bindings/pinctrl/stm32-pinfunc.h @@ -33,6 +33,11 @@ #define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode)) +#define STM32_PIN_NSEC (1 << 31) + +#define STM32_PINMUX_NSEC(port, line, mode) \ + (STM32_PIN_NSEC | STM32_PINMUX((port), (line), (mode))) + /* package information */ #define STM32MP_PKG_AA 0x1 #define STM32MP_PKG_AB 0x2 From a229b2a54f024a1cb81e5454326f6ad84f2eb125 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Sep 2024 19:46:23 +0200 Subject: [PATCH 03/20] dts: stm32: define SoC GPIO banks that are firewall controllers Add property #access-controller-cells to GPIO banks that register to the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/dts/stm32mp131.dtsi | 9 +++++++++ core/arch/arm/dts/stm32mp151.dtsi | 1 + core/arch/arm/dts/stm32mp251.dtsi | 12 ++++++++++++ 3 files changed, 22 insertions(+) diff --git a/core/arch/arm/dts/stm32mp131.dtsi b/core/arch/arm/dts/stm32mp131.dtsi index 45aca5b9d30..1a4917bb99a 100644 --- a/core/arch/arm/dts/stm32mp131.dtsi +++ b/core/arch/arm/dts/stm32mp131.dtsi @@ -291,6 +291,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOA>; reg = <0x0 0x400>; st,bank-name = "GPIOA"; @@ -303,6 +304,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOB>; reg = <0x1000 0x400>; st,bank-name = "GPIOB"; @@ -315,6 +317,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOC>; reg = <0x2000 0x400>; st,bank-name = "GPIOC"; @@ -327,6 +330,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOD>; reg = <0x3000 0x400>; st,bank-name = "GPIOD"; @@ -339,6 +343,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOE>; reg = <0x4000 0x400>; st,bank-name = "GPIOE"; @@ -351,6 +356,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOF>; reg = <0x5000 0x400>; st,bank-name = "GPIOF"; @@ -363,6 +369,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOG>; reg = <0x6000 0x400>; st,bank-name = "GPIOG"; @@ -375,6 +382,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOH>; reg = <0x7000 0x400>; st,bank-name = "GPIOH"; @@ -387,6 +395,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; clocks = <&rcc GPIOI>; reg = <0x8000 0x400>; st,bank-name = "GPIOI"; diff --git a/core/arch/arm/dts/stm32mp151.dtsi b/core/arch/arm/dts/stm32mp151.dtsi index 31a5e247edb..f5ab0d28f88 100644 --- a/core/arch/arm/dts/stm32mp151.dtsi +++ b/core/arch/arm/dts/stm32mp151.dtsi @@ -517,6 +517,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0 0x400>; clocks = <&rcc GPIOZ>; st,bank-name = "GPIOZ"; diff --git a/core/arch/arm/dts/stm32mp251.dtsi b/core/arch/arm/dts/stm32mp251.dtsi index f7f5e7ec8b9..a662e05d57f 100644 --- a/core/arch/arm/dts/stm32mp251.dtsi +++ b/core/arch/arm/dts/stm32mp251.dtsi @@ -286,6 +286,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x0 0x400>; clocks = <&rcc CK_BUS_GPIOA>; st,bank-name = "GPIOA"; @@ -297,6 +298,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x10000 0x400>; clocks = <&rcc CK_BUS_GPIOB>; st,bank-name = "GPIOB"; @@ -308,6 +310,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x20000 0x400>; clocks = <&rcc CK_BUS_GPIOC>; st,bank-name = "GPIOC"; @@ -319,6 +322,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x30000 0x400>; clocks = <&rcc CK_BUS_GPIOD>; st,bank-name = "GPIOD"; @@ -330,6 +334,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x40000 0x400>; clocks = <&rcc CK_BUS_GPIOE>; st,bank-name = "GPIOE"; @@ -341,6 +346,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x50000 0x400>; clocks = <&rcc CK_BUS_GPIOF>; st,bank-name = "GPIOF"; @@ -352,6 +358,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x60000 0x400>; clocks = <&rcc CK_BUS_GPIOG>; st,bank-name = "GPIOG"; @@ -363,6 +370,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x70000 0x400>; clocks = <&rcc CK_BUS_GPIOH>; st,bank-name = "GPIOH"; @@ -374,6 +382,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x80000 0x400>; clocks = <&rcc CK_BUS_GPIOI>; st,bank-name = "GPIOI"; @@ -385,6 +394,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0x90000 0x400>; clocks = <&rcc CK_BUS_GPIOJ>; st,bank-name = "GPIOJ"; @@ -396,6 +406,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0xa0000 0x400>; clocks = <&rcc CK_BUS_GPIOK>; st,bank-name = "GPIOK"; @@ -415,6 +426,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + #access-controller-cells = <1>; reg = <0 0x400>; clocks = <&rcc CK_BUS_GPIOZ>; st,bank-name = "GPIOZ"; From affbb396cee057375d42e48064b99711a2f40c9a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 19 Jul 2024 11:30:01 +0200 Subject: [PATCH 04/20] dts: stm32: most stm32mp15 UARTs pinctrl are non-secure On STM32MP15 based devices, UART2/3/4/5/6/7/8 cannot be secured. Explicitly state that in the pinctrl nodes. This change ease the use of a non-secure UART for OP-TEE output console on STM32MP15 based boards. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/dts/stm32mp15-pinctrl.dtsi | 184 +++++++++++------------ 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi index 7edff9ca819..acd12c5ae13 100644 --- a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi @@ -1830,356 +1830,356 @@ uart4_pins_a: uart4-0 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART4_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART4_RX */ + pinmux = ; /* UART4_RX */ bias-disable; }; }; uart4_idle_pins_a: uart4-idle-0 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART4_TX */ }; pins2 { - pinmux = ; /* UART4_RX */ + pinmux = ; /* UART4_RX */ bias-disable; }; }; uart4_sleep_pins_a: uart4-sleep-0 { pins { - pinmux = , /* UART4_TX */ - ; /* UART4_RX */ + pinmux = , /* UART4_TX */ + ; /* UART4_RX */ }; }; uart4_pins_b: uart4-1 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART4_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART4_RX */ + pinmux = ; /* UART4_RX */ bias-disable; }; }; uart4_pins_c: uart4-2 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART4_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART4_RX */ + pinmux = ; /* UART4_RX */ bias-disable; }; }; uart7_pins_a: uart7-0 { pins1 { - pinmux = ; /* UART7_TX */ + pinmux = ; /* UART7_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* UART7_RX */ - , /* UART7_CTS */ - ; /* UART7_RTS */ + pinmux = , /* UART7_RX */ + , /* UART7_CTS */ + ; /* UART7_RTS */ bias-disable; }; }; uart7_pins_b: uart7-1 { pins1 { - pinmux = ; /* UART7_TX */ + pinmux = ; /* UART7_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART7_RX */ + pinmux = ; /* UART7_RX */ bias-disable; }; }; uart7_pins_c: uart7-2 { pins1 { - pinmux = ; /* UART7_TX */ + pinmux = ; /* UART7_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART7_RX */ + pinmux = ; /* UART7_RX */ bias-pull-up; }; }; uart7_idle_pins_c: uart7-idle-2 { pins1 { - pinmux = ; /* UART7_TX */ + pinmux = ; /* UART7_TX */ }; pins2 { - pinmux = ; /* UART7_RX */ + pinmux = ; /* UART7_RX */ bias-pull-up; }; }; uart7_sleep_pins_c: uart7-sleep-2 { pins { - pinmux = , /* UART7_TX */ - ; /* UART7_RX */ + pinmux = , /* UART7_TX */ + ; /* UART7_RX */ }; }; uart8_pins_a: uart8-0 { pins1 { - pinmux = ; /* UART8_TX */ + pinmux = ; /* UART8_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART8_RX */ + pinmux = ; /* UART8_RX */ bias-disable; }; }; uart8_rtscts_pins_a: uart8rtscts-0 { pins { - pinmux = , /* UART8_RTS */ - ; /* UART8_CTS */ + pinmux = , /* UART8_RTS */ + ; /* UART8_CTS */ bias-disable; }; }; usart2_pins_a: usart2-0 { pins1 { - pinmux = , /* USART2_TX */ - ; /* USART2_RTS */ + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ bias-disable; }; }; usart2_sleep_pins_a: usart2-sleep-0 { pins { - pinmux = , /* USART2_TX */ - , /* USART2_RTS */ - , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_TX */ + , /* USART2_RTS */ + , /* USART2_RX */ + ; /* USART2_CTS_NSS */ }; }; usart2_pins_b: usart2-1 { pins1 { - pinmux = , /* USART2_TX */ - ; /* USART2_RTS */ + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ bias-disable; }; }; usart2_sleep_pins_b: usart2-sleep-1 { pins { - pinmux = , /* USART2_TX */ - , /* USART2_RTS */ - , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_TX */ + , /* USART2_RTS */ + , /* USART2_RX */ + ; /* USART2_CTS_NSS */ }; }; usart2_pins_c: usart2-2 { pins1 { - pinmux = , /* USART2_TX */ - ; /* USART2_RTS */ + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ bias-disable; }; }; usart2_idle_pins_c: usart2-idle-2 { pins1 { - pinmux = , /* USART2_TX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_TX */ + ; /* USART2_CTS_NSS */ }; pins2 { - pinmux = ; /* USART2_RTS */ + pinmux = ; /* USART2_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins3 { - pinmux = ; /* USART2_RX */ + pinmux = ; /* USART2_RX */ bias-disable; }; }; usart2_sleep_pins_c: usart2-sleep-2 { pins { - pinmux = , /* USART2_TX */ - , /* USART2_RTS */ - , /* USART2_RX */ - ; /* USART2_CTS_NSS */ + pinmux = , /* USART2_TX */ + , /* USART2_RTS */ + , /* USART2_RX */ + ; /* USART2_CTS_NSS */ }; }; usart3_pins_a: usart3-0 { pins1 { - pinmux = ; /* USART3_TX */ + pinmux = ; /* USART3_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* USART3_RX */ + pinmux = ; /* USART3_RX */ bias-disable; }; }; usart3_pins_b: usart3-1 { pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_RTS */ + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART3_RX */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ bias-pull-up; }; }; usart3_idle_pins_b: usart3-idle-1 { pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_TX */ + ; /* USART3_CTS_NSS */ }; pins2 { - pinmux = ; /* USART3_RTS */ + pinmux = ; /* USART3_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins3 { - pinmux = ; /* USART3_RX */ + pinmux = ; /* USART3_RX */ bias-pull-up; }; }; usart3_sleep_pins_b: usart3-sleep-1 { pins { - pinmux = , /* USART3_TX */ - , /* USART3_RTS */ - , /* USART3_CTS_NSS */ - ; /* USART3_RX */ + pinmux = , /* USART3_TX */ + , /* USART3_RTS */ + , /* USART3_CTS_NSS */ + ; /* USART3_RX */ }; }; usart3_pins_c: usart3-2 { pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_RTS */ + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART3_RX */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ bias-pull-up; }; }; usart3_idle_pins_c: usart3-idle-2 { pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_TX */ + ; /* USART3_CTS_NSS */ }; pins2 { - pinmux = ; /* USART3_RTS */ + pinmux = ; /* USART3_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins3 { - pinmux = ; /* USART3_RX */ + pinmux = ; /* USART3_RX */ bias-pull-up; }; }; usart3_sleep_pins_c: usart3-sleep-2 { pins { - pinmux = , /* USART3_TX */ - , /* USART3_RTS */ - , /* USART3_CTS_NSS */ - ; /* USART3_RX */ + pinmux = , /* USART3_TX */ + , /* USART3_RTS */ + , /* USART3_CTS_NSS */ + ; /* USART3_RX */ }; }; usart3_pins_d: usart3-3 { pins1 { - pinmux = , /* USART3_TX */ - ; /* USART3_RTS */ + pinmux = , /* USART3_TX */ + ; /* USART3_RTS */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* USART3_RX */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_RX */ + ; /* USART3_CTS_NSS */ bias-disable; }; }; usart3_idle_pins_d: usart3-idle-3 { pins1 { - pinmux = , /* USART3_TX */ - , /* USART3_RTS */ - ; /* USART3_CTS_NSS */ + pinmux = , /* USART3_TX */ + , /* USART3_RTS */ + ; /* USART3_CTS_NSS */ }; pins2 { - pinmux = ; /* USART3_RX */ + pinmux = ; /* USART3_RX */ bias-disable; }; }; usart3_sleep_pins_d: usart3-sleep-3 { pins { - pinmux = , /* USART3_TX */ - , /* USART3_RTS */ - , /* USART3_CTS_NSS */ - ; /* USART3_RX */ + pinmux = , /* USART3_TX */ + , /* USART3_RTS */ + , /* USART3_CTS_NSS */ + ; /* USART3_RX */ }; }; From 086300943c576c990fc5b9b06c497963422bf153 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 16 Sep 2024 15:27:12 +0200 Subject: [PATCH 05/20] dts: stm32: refine STM32MP15 secure/non-secure I2C4 pinctrl states Explicitly state that legacy pinctrl phandles i2c4_pins_a and i2c4_sleep_pins_a refer to non-secure I2C4 pin muxing on STM32MP15 based platforms. Define secure I2C4 bus pinctrl states for boards that use the I2C4 bus in secure state on STM32MP15 SoCs. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/dts/stm32mp15-pinctrl.dtsi | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi index acd12c5ae13..7806110a4c3 100644 --- a/core/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp15-pinctrl.dtsi @@ -2214,6 +2214,23 @@ }; i2c4_pins_a: i2c4-0 { + pins { + pinmux = , /* I2C4_SCL */ + ; /* I2C4_SDA */ + bias-disable; + drive-open-drain; + slew-rate = <0>; + }; + }; + + i2c4_sleep_pins_a: i2c4-sleep-0 { + pins { + pinmux = , /* I2C4_SCL */ + ; /* I2C4_SDA */ + }; + }; + + i2c4_secure_pins_a: i2c4-sec-0 { pins { pinmux = , /* I2C4_SCL */ ; /* I2C4_SDA */ @@ -2223,7 +2240,7 @@ }; }; - i2c4_sleep_pins_a: i2c4-sleep-0 { + i2c4_secure_sleep_pins_a: i2c4-sec-sleep-0 { pins { pinmux = , /* I2C4_SCL */ ; /* I2C4_SDA */ From ba913d5c5d149debdc934f35e7974f9ec8e8f1ca Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 17 Sep 2024 10:03:36 +0200 Subject: [PATCH 06/20] dts: stm32: refine STM32MP13 secure/non-secure USART4 pinctrl states Explicitly state that legacy pinctrl phandles usart4_pins_a refer to non-secure USART4 pin muxing, used in STM32MP13 based boards for OP-TEE console using a non-secure UART bus. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/dts/stm32mp13-pinctrl.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/arch/arm/dts/stm32mp13-pinctrl.dtsi b/core/arch/arm/dts/stm32mp13-pinctrl.dtsi index 6bf84198769..fc7289df298 100644 --- a/core/arch/arm/dts/stm32mp13-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp13-pinctrl.dtsi @@ -27,13 +27,13 @@ uart4_pins_a: uart4-0 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART4_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* UART4_RX */ + pinmux = ; /* UART4_RX */ bias-disable; }; }; From a78abea955127a94243e60c2b0f1725a96177a39 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 17 Sep 2024 09:46:27 +0200 Subject: [PATCH 07/20] dts: stm32: refine STM32MP25 secure/non-secure USART2 pinctrl states Explicitly state that legacy pinctrl phandles usart2_pins_a refer to non-secure USART2 pin muxing, used in STM32MP23 and STM32MP25 based boards for OP-TEE console using a non-secure UART bus. Define secure USART2 bus pinctrl states for board that needs to use the USART2 bus in secure state. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/dts/stm32mp25-pinctrl.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/arch/arm/dts/stm32mp25-pinctrl.dtsi b/core/arch/arm/dts/stm32mp25-pinctrl.dtsi index 0d417080b5f..0fa9d60e28f 100644 --- a/core/arch/arm/dts/stm32mp25-pinctrl.dtsi +++ b/core/arch/arm/dts/stm32mp25-pinctrl.dtsi @@ -7,6 +7,19 @@ &pinctrl { usart2_pins_a: usart2-0 { + pins1 { + pinmux = ; /* USART2_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* USART2_RX */ + bias-disable; + }; + }; + + usart2_secure_pins_a: usart2-sec-0 { pins1 { pinmux = ; /* USART2_TX */ bias-disable; From 37541a9db62d9036967e361ef9544d3d39ca5361 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 19 Jul 2024 10:18:38 +0200 Subject: [PATCH 08/20] drivers: stm32_gpio: check GPIO is not already consumed Check that a GPIO requested by a consumer is not already consumed by another device. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 469cf7bbfd9..7cef78b60f5 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -618,6 +618,7 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, struct gpio **out_gpio) { TEE_Result res = TEE_ERROR_GENERIC; + struct stm32_gpio_pm_state *reg_state = NULL; struct stm32_gpio_pm_state *state = NULL; struct stm32_gpio_bank *bank = data; struct gpio *gpio = NULL; @@ -644,6 +645,19 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, return TEE_ERROR_OUT_OF_MEMORY; } + SLIST_FOREACH(reg_state, &consumed_gpios_head, link) { + if (reg_state->gpio_pinctrl.bank == bank->bank_id && + reg_state->gpio_pinctrl.pin == gpio->pin) { + EMSG("node %s: GPIO %c%u is used by another device", + fdt_get_name(pargs->fdt, pargs->consumer_node, + NULL), + bank->bank_id + 'A', gpio->pin); + free(state); + free(gpio); + return TEE_ERROR_GENERIC; + } + } + state->gpio_pinctrl.pin = gpio->pin; state->gpio_pinctrl.bank = bank->bank_id; SLIST_INSERT_HEAD(&consumed_gpios_head, state, link); From 8625e4affed1f360e3fade87f4f1a88ab1a633f2 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Sep 2024 15:33:55 +0200 Subject: [PATCH 09/20] drivers: stm32_gpio: factorize apply_rif_config() Change apply_rif_config() to be able to call it for a subset of pins in a GPIO bank. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 44 ++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 7cef78b60f5..68f3917a412 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -741,14 +741,15 @@ static bool bank_is_registered(const void *fdt, int node) } #ifdef CFG_STM32_RIF -static TEE_Result handle_available_semaphores(struct stm32_gpio_bank *bank) +static TEE_Result handle_available_semaphores(struct stm32_gpio_bank *bank, + uint32_t gpios_mask) { TEE_Result res = TEE_ERROR_GENERIC; uint32_t cidcfgr = 0; unsigned int i = 0; for (i = 0 ; i < bank->ngpios; i++) { - if (!(BIT(i) & bank->rif_cfg->access_mask[0])) + if (!(BIT(i) & gpios_mask)) continue; cidcfgr = io_read32(bank->base + GPIO_CIDCFGR(i)); @@ -780,7 +781,8 @@ static TEE_Result handle_available_semaphores(struct stm32_gpio_bank *bank) return TEE_SUCCESS; } -static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) +static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank, + uint32_t gpios_mask) { TEE_Result res = TEE_ERROR_GENERIC; unsigned int i = 0; @@ -793,7 +795,7 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) if (bank->is_tdcid) { for (i = 0; i < bank->ngpios; i++) { - if (!(BIT(i) & bank->rif_cfg->access_mask[0])) + if (!(BIT(i) & gpios_mask)) continue; /* @@ -806,18 +808,16 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) GPIO_CIDCFGR_CONF_MASK); } } else { - res = handle_available_semaphores(bank); + res = handle_available_semaphores(bank, gpios_mask); if (res) panic(); } /* Security and privilege RIF configuration */ - io_clrsetbits32(bank->base + GPIO_PRIVCFGR_OFFSET, - bank->rif_cfg->access_mask[0], - bank->rif_cfg->priv_conf[0]); - io_clrsetbits32(bank->base + GPIO_SECR_OFFSET, - bank->rif_cfg->access_mask[0], - bank->rif_cfg->sec_conf[0]); + io_mask32(bank->base + GPIO_PRIVCFGR_OFFSET, + bank->rif_cfg->priv_conf[0], gpios_mask); + io_mask32(bank->base + GPIO_SECR_OFFSET, + bank->rif_cfg->sec_conf[0], gpios_mask); if (!bank->is_tdcid) { res = TEE_SUCCESS; @@ -825,7 +825,7 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) } for (i = 0; i < bank->ngpios; i++) { - if (!(BIT(i) & bank->rif_cfg->access_mask[0])) + if (!(BIT(i) & gpios_mask)) continue; io_clrsetbits32(bank->base + GPIO_CIDCFGR(i), @@ -840,7 +840,7 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) io_setbits32(bank->base + GPIO_RCFGLOCKR_OFFSET, bank->rif_cfg->lock_conf[0]); - res = handle_available_semaphores(bank); + res = handle_available_semaphores(bank, gpios_mask); if (res) panic(); @@ -848,16 +848,15 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) if (IS_ENABLED(CFG_TEE_CORE_DEBUG)) { /* Check that RIF config are applied, panic otherwise */ if ((io_read32(bank->base + GPIO_PRIVCFGR_OFFSET) & - bank->rif_cfg->access_mask[0]) != - bank->rif_cfg->priv_conf[0]) { + gpios_mask) != + (bank->rif_cfg->priv_conf[0] & gpios_mask)) { EMSG("GPIO bank%c priv conf is incorrect", 'A' + bank->bank_id); panic(); } - if ((io_read32(bank->base + GPIO_SECR_OFFSET) & - bank->rif_cfg->access_mask[0]) != - bank->rif_cfg->sec_conf[0]) { + if ((io_read32(bank->base + GPIO_SECR_OFFSET) & gpios_mask) != + (bank->rif_cfg->sec_conf[0] & gpios_mask)) { EMSG("GPIO bank %c sec conf is incorrect", 'A' + bank->bank_id); panic(); @@ -869,7 +868,8 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank) return res; } #else /* CFG_STM32_RIF */ -static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank __unused) +static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank __unused, + uint32_t gpios_mask __unused) { return TEE_SUCCESS; } @@ -1269,7 +1269,8 @@ static TEE_Result stm32_gpio_sec_config_resume(void) bank->rif_cfg->access_mask[0] = GENMASK_32(bank->ngpios, 0); - res = apply_rif_config(bank); + res = apply_rif_config(bank, + bank->rif_cfg->access_mask[0]); if (res) { EMSG("Failed to set GPIO bank %c RIF config", 'A' + bank->bank_id); @@ -1334,7 +1335,8 @@ static TEE_Result apply_sec_cfg(void) continue; if (bank->rif_cfg) { - res = apply_rif_config(bank); + res = apply_rif_config(bank, + bank->rif_cfg->access_mask[0]); if (res) { EMSG("Failed to set GPIO bank %c RIF config", 'A' + bank->bank_id); From 6007d0f6b49eb239523d82569396dc4b1b4b6ce6 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 2 Sep 2024 15:41:50 +0200 Subject: [PATCH 10/20] drivers: stm32_gpio: register to firewall framework Register secure aware STM32 GPIO banks to the firewall framework as a firewall controller to allow GPIO and pinctrl consumer devices to load alternate configurations for pins. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 105 +++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 68f3917a412..b5f3a1f5aa8 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -9,11 +9,12 @@ #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -875,6 +876,69 @@ static TEE_Result apply_rif_config(struct stm32_gpio_bank *bank __unused, } #endif /* CFG_STM32_RIF */ +/* Forward reference to stm32_gpio_set_conf_sec() defined below */ +static void stm32_gpio_set_conf_sec(struct stm32_gpio_bank *bank); + +static TEE_Result stm32_gpio_fw_configure(struct firewall_query *firewall) +{ + struct stm32_gpio_bank *bank = firewall->ctrl->priv; + uint32_t firewall_arg = 0; + uint32_t gpios_mask = 0; + bool secure = true; + + assert(bank->sec_support); + + if (firewall->arg_count != 1) + return TEE_ERROR_BAD_PARAMETERS; + + firewall_arg = firewall->args[0]; + + if (bank->rif_cfg) { + gpios_mask = BIT(RIF_CHANNEL_ID(firewall_arg)); + + /* We're about to change a specific GPIO config */ + bank->rif_cfg->access_mask[0] |= gpios_mask; + + /* + * Update bank RIF config with firewall configuration data + * and apply it. + */ + stm32_rif_parse_cfg(firewall_arg, bank->rif_cfg, + bank->ngpios); + return apply_rif_config(bank, gpios_mask); + } + + /* + * Non RIF GPIO banks use a single cell as a bit mask (bits 0 to 15) + * to define the a group of GPIO pins (one or several) to configure + * for that bank, and GPIO_STM32_NSEC bit flag to set if these pins + * are non-secure (flag set) or non-secure (flag cleared). + */ + gpios_mask = firewall_arg & GENMASK_32(15, 0); + + secure = !(firewall_arg & GPIO_STM32_NSEC); + + if (gpios_mask & ~GENMASK_32(bank->ngpios, 0)) { + EMSG("Invalid bitmask %#"PRIx32" for GPIO bank %c", + gpios_mask, 'A' + bank->bank_id); + return TEE_ERROR_GENERIC; + } + + /* Update bank secure register configuration data and apply it */ + if (secure) + bank->seccfgr |= gpios_mask; + else + bank->seccfgr &= ~gpios_mask; + + stm32_gpio_set_conf_sec(bank); + + return TEE_SUCCESS; +} + +static const struct firewall_controller_ops stm32_gpio_firewall_ops = { + .set_conf = stm32_gpio_fw_configure, +}; + static void stm32_gpio_save_rif_config(struct stm32_gpio_bank *bank) { size_t i = 0; @@ -1020,6 +1084,41 @@ static TEE_Result dt_stm32_gpio_bank(const void *fdt, int node, return TEE_SUCCESS; } +static TEE_Result stm32_gpio_firewall_register(const void *fdt, int node, + struct stm32_gpio_bank *bank) +{ + struct firewall_controller *controller = NULL; + TEE_Result res = TEE_ERROR_GENERIC; + char bank_name[] = "gpio-bank-X"; + char *name = NULL; + + if (!IS_ENABLED(CFG_DRIVERS_FIREWALL) || + !bank->sec_support) + return TEE_SUCCESS; + + controller = calloc(1, sizeof(*controller)); + if (!controller) + return TEE_ERROR_OUT_OF_MEMORY; + + bank_name[sizeof(bank_name) - 2] = 'A' + bank->bank_id; + name = strdup(bank_name); + + controller->name = name; + controller->priv = bank; + controller->ops = &stm32_gpio_firewall_ops; + + if (!controller->name) + EMSG("Warning: out of memory to store bank name"); + + res = firewall_dt_controller_register(fdt, node, controller); + if (res) { + free(name); + free(controller); + } + + return res; +} + /* Parse a pinctrl node to register the GPIO banks it describes */ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, const void *compat_data) @@ -1064,6 +1163,10 @@ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, if (res) panic(); + res = stm32_gpio_firewall_register(fdt, b_node, bank); + if (res) + panic(); + STAILQ_INSERT_TAIL(&bank_list, bank, link); } else { if (len != -FDT_ERR_NOTFOUND) From 1d8bbf92de027a9ea9aab7e8eaedc16b8b2bae1b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 19 Jul 2024 09:40:12 +0200 Subject: [PATCH 11/20] drivers: stm32_gpio: acquire semaphore when GPIO/pinctrl are used Release RIF semaphore taken at GPIO bank initialization and acquire them only when the GPIO or pinctrl is used or when a firewall configuration is requested. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 126 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index b5f3a1f5aa8..b5d00b40082 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -343,6 +343,10 @@ static void stm32_gpio_set_direction(struct gpio_chip *chip, static TEE_Result consumed_gpios_pm(enum pm_op op, unsigned int pm_hint, const struct pm_callback_handle *pm_hdl); +/* Forward reference to RIF semaphore release helper function */ +static void release_rif_semaphore_if_acquired(struct stm32_gpio_bank *bank, + unsigned int pin); + static void stm32_gpio_put_gpio(struct gpio_chip *chip, struct gpio *gpio) { struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); @@ -360,6 +364,7 @@ static void stm32_gpio_put_gpio(struct gpio_chip *chip, struct gpio *gpio) SLIST_REMOVE(&consumed_gpios_head, state, stm32_gpio_pm_state, link); unregister_pm_driver_cb(consumed_gpios_pm, state); + release_rif_semaphore_if_acquired(bank, gpio->pin); free(state); free(gpio); break; @@ -394,6 +399,82 @@ static struct stm32_gpio_bank *stm32_gpio_get_bank(unsigned int bank_id) panic(); } +#if defined(CFG_STM32_RIF) +static TEE_Result acquire_rif_semaphore_if_needed(struct stm32_gpio_bank *bank, + unsigned int pin) +{ + TEE_Result res = TEE_SUCCESS; + uint32_t cidcfgr = 0; + + if (!bank->rif_cfg) + return TEE_SUCCESS; + + res = clk_enable(bank->clock); + if (res) + return res; + + cidcfgr = io_read32(bank->base + GPIO_CIDCFGR(pin)); + + if (stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1)) + res = stm32_rif_acquire_semaphore(bank->base + GPIO_SEMCR(pin), + GPIO_MAX_CID_SUPPORTED); + + clk_disable(bank->clock); + + return res; +} + +static uint32_t semaphore_current_cid(struct stm32_gpio_bank *bank, + unsigned int pin) +{ + return (io_read32(bank->base + GPIO_SEMCR(pin)) >> + _CIDCFGR_SCID_SHIFT) & + GENMASK_32(GPIO_MAX_CID_SUPPORTED - 1, 0); +} + +static void release_rif_semaphore_if_acquired(struct stm32_gpio_bank *bank, + unsigned int pin) +{ + TEE_Result res = TEE_ERROR_GENERIC; + uint32_t cidcfgr = 0; + + if (!bank->rif_cfg) + return; + + res = clk_enable(bank->clock); + if (res) + panic(); + + cidcfgr = io_read32(bank->base + GPIO_CIDCFGR(pin)); + + if (stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1) && + semaphore_current_cid(bank, pin) == RIF_CID1) { + res = stm32_rif_release_semaphore(bank->base + GPIO_SEMCR(pin), + GPIO_MAX_CID_SUPPORTED); + if (res) { + EMSG("Failed to release GPIO %c%u semaphore", + bank->bank_id + 'A', pin); + panic(); + } + } + + clk_disable(bank->clock); +} +#else +static TEE_Result +acquire_rif_semaphore_if_needed(struct stm32_gpio_bank *bank __unused, + unsigned int pin __unused) +{ + return TEE_SUCCESS; +} + +static void +release_rif_semaphore_if_acquired(struct stm32_gpio_bank *bank __unused, + unsigned int pin __unused) +{ +} +#endif /*CFG_STM32_RIF*/ + /* Save to output @cfg the current GPIO (@bank_id/@pin) configuration */ static void get_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) { @@ -619,6 +700,7 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, struct gpio **out_gpio) { TEE_Result res = TEE_ERROR_GENERIC; + const char *consumer_name __maybe_unused = NULL; struct stm32_gpio_pm_state *reg_state = NULL; struct stm32_gpio_pm_state *state = NULL; struct stm32_gpio_bank *bank = data; @@ -630,6 +712,9 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, uint32_t pupd = 0; uint32_t mode = 0; + consumer_name = fdt_get_name(pargs->fdt, pargs->consumer_node, + NULL); + res = gpio_dt_alloc_pin(pargs, &gpio); if (res) return res; @@ -659,6 +744,13 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, } } + res = acquire_rif_semaphore_if_needed(bank, gpio->pin); + if (res) { + EMSG("Failed to acquire GPIO %c%u semaphore for node %s", + bank->bank_id + 'A', gpio->pin, consumer_name); + return res; + } + state->gpio_pinctrl.pin = gpio->pin; state->gpio_pinctrl.bank = bank->bank_id; SLIST_INSERT_HEAD(&consumed_gpios_head, state, link); @@ -1201,8 +1293,30 @@ static TEE_Result stm32_pinctrl_conf_apply(struct pinconf *conf) { struct stm32_pinctrl_array *ref = conf->priv; struct stm32_pinctrl *p = ref->pinctrl; + struct stm32_gpio_bank *bank = NULL; + TEE_Result res = TEE_ERROR_GENERIC; size_t pin_count = ref->count; size_t n = 0; + bool error = false; + + for (n = 0; n < pin_count; n++) { + bank = stm32_gpio_get_bank(p[n].bank); + res = acquire_rif_semaphore_if_needed(bank, p[n].pin); + if (res) { + EMSG("Failed to acquire GPIO %c%u semaphore", + bank->bank_id + 'A', p[n].pin); + error = true; + } + } + + if (error) { + for (n = 0; n < pin_count; n++) { + bank = stm32_gpio_get_bank(p[n].bank); + release_rif_semaphore_if_acquired(bank, p[n].pin); + } + + return TEE_ERROR_SECURITY; + } for (n = 0; n < pin_count; n++) set_gpio_cfg(p[n].bank, p[n].pin, &p[n].cfg); @@ -1432,6 +1546,7 @@ static TEE_Result apply_sec_cfg(void) { TEE_Result res = TEE_ERROR_GENERIC; struct stm32_gpio_bank *bank = NULL; + unsigned int pin = 0; STAILQ_FOREACH(bank, &bank_list, link) { if (bank->ready) @@ -1448,6 +1563,17 @@ static TEE_Result apply_sec_cfg(void) free(bank); return res; } + + /* + * Semaphores for pinctrl and GPIO are taken when + * these are used (pinctrl state applied, GPIO + * consumed) or when an explicit firewall configuration + * is requested through the firewall framework. + * Therefore release here the taken semaphores. + */ + for (pin = 0; pin < bank->ngpios; pin++) + release_rif_semaphore_if_acquired(bank, pin); + } else { stm32_gpio_set_conf_sec(bank); } From 8d5854fe4888807f63b97887a78c9d4bab844de7 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 5 Dec 2024 18:01:41 +0100 Subject: [PATCH 12/20] drivers: stm32_gpio: check secure state of consumed GPIOs STM32 GPIO driver now verifies that any GPIO consumed by OP-TEE can be accessed and has the expected secure hardening configuration. If a driver attempts to consume a GPIO that cannot be accessed by OP-TEE, core panics. When a GPIO is used with an inappropriate secure configuration state, STM32 GPIO driver panics or prints an info level message, depending on CFG_INSECURE. This change is based on the recently added GPIO_STM32_NSEC bindings macro in STM32 GPIO driver DT bindings header file that is a hint on whether a consumed GPIO is expected secure or shared with non-secure world. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 82 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index b5d00b40082..fb661410f4f 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -400,6 +400,36 @@ static struct stm32_gpio_bank *stm32_gpio_get_bank(unsigned int bank_id) } #if defined(CFG_STM32_RIF) +static bool pin_is_accessible(struct stm32_gpio_bank *bank, unsigned int pin) +{ + bool accessible = false; + uint32_t cidcfgr = 0; + + if (!bank->rif_cfg) + return true; + + if (clk_enable(bank->clock)) + panic(); + + cidcfgr = io_read32(bank->base + GPIO_CIDCFGR(pin)); + + if (!(cidcfgr & _CIDCFGR_CFEN)) { + /* Resource can be accessed when CID filtering is disabled */ + accessible = true; + } else if (stm32_rif_scid_ok(cidcfgr, GPIO_CIDCFGR_SCID_MASK, + RIF_CID1)) { + /* Resource can be accessed if CID1 is statically allowed */ + accessible = true; + } else if (stm32_rif_semaphore_enabled_and_ok(cidcfgr, RIF_CID1)) { + /* CID1 is allowed to request the semaphore */ + accessible = true; + } + + clk_disable(bank->clock); + + return accessible; +} + static TEE_Result acquire_rif_semaphore_if_needed(struct stm32_gpio_bank *bank, unsigned int pin) { @@ -461,6 +491,12 @@ static void release_rif_semaphore_if_acquired(struct stm32_gpio_bank *bank, clk_disable(bank->clock); } #else +static bool pin_is_accessible(struct stm32_gpio_bank *bank __unused, + unsigned int pin __unused) +{ + return true; +} + static TEE_Result acquire_rif_semaphore_if_needed(struct stm32_gpio_bank *bank __unused, unsigned int pin __unused) @@ -475,6 +511,22 @@ release_rif_semaphore_if_acquired(struct stm32_gpio_bank *bank __unused, } #endif /*CFG_STM32_RIF*/ +static bool pin_is_secure(struct stm32_gpio_bank *bank, unsigned int pin) +{ + bool secure = false; + + if (bank->rif_cfg || bank->sec_support) { + if (clk_enable(bank->clock)) + panic(); + + secure = io_read32(bank->base + GPIO_SECR_OFFSET) & BIT(pin); + + clk_disable(bank->clock); + } + + return secure; +} + /* Save to output @cfg the current GPIO (@bank_id/@pin) configuration */ static void get_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) { @@ -707,6 +759,7 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, struct gpio *gpio = NULL; unsigned int shift_1b = 0; unsigned int shift_2b = 0; + bool gpio_secure = true; uint32_t exceptions = 0; uint32_t otype = 0; uint32_t pupd = 0; @@ -725,6 +778,9 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, return TEE_ERROR_GENERIC; } + if (gpio->dt_flags & GPIO_STM32_NSEC) + gpio_secure = false; + state = calloc(1, sizeof(*state)); if (!state) { free(gpio); @@ -735,15 +791,19 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, if (reg_state->gpio_pinctrl.bank == bank->bank_id && reg_state->gpio_pinctrl.pin == gpio->pin) { EMSG("node %s: GPIO %c%u is used by another device", - fdt_get_name(pargs->fdt, pargs->consumer_node, - NULL), - bank->bank_id + 'A', gpio->pin); + consumer_name, bank->bank_id + 'A', gpio->pin); free(state); free(gpio); return TEE_ERROR_GENERIC; } } + if (!pin_is_accessible(bank, gpio->pin)) { + EMSG("node %s requests pin on GPIO %c%u which access is denied", + consumer_name, bank->bank_id + 'A', gpio->pin); + panic(); + } + res = acquire_rif_semaphore_if_needed(bank, gpio->pin); if (res) { EMSG("Failed to acquire GPIO %c%u semaphore for node %s", @@ -751,6 +811,22 @@ static TEE_Result stm32_gpio_get_dt(struct dt_pargs *pargs, void *data, return res; } + if (gpio_secure && !(bank->rif_cfg || bank->sec_support)) { + EMSG("node %s requests secure GPIO %c%u that cannot be secured", + consumer_name, bank->bank_id + 'A', gpio->pin); + panic(); + } + + if (gpio_secure != pin_is_secure(bank, gpio->pin)) { + IMSG("WARNING: node %s requests %s GPIO %c%u but pin is %s. Check st,protreg in GPIO bank node %s", + consumer_name, gpio_secure ? "secure" : "non-secure", + bank->bank_id + 'A', gpio->pin, + pin_is_secure(bank, gpio->pin) ? "secure" : "non-secure", + fdt_get_name(pargs->fdt, pargs->phandle_node, NULL)); + if (!IS_ENABLED(CFG_INSECURE)) + panic(); + } + state->gpio_pinctrl.pin = gpio->pin; state->gpio_pinctrl.bank = bank->bank_id; SLIST_INSERT_HEAD(&consumed_gpios_head, state, link); From bd976d6fcda3f1acdefd6f0a078806de0e69d02b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:12:17 +0200 Subject: [PATCH 13/20] drivers: stm32_gpio: check secure state of pinctrl states Make STM32 GPIO driver to verify that any all pins of applied pinctrl states be accessed and has the expected secure hardening configuration when used. Non-secure pins must have the STM32_PIN_NSEC bit set in the pin handler argument unless what the pin is expected to be secure. The driver returns an error when the expected secure state of a pin does not match its effective secure state or it cannot be accessed, unless CFG_INSECURE is enabled in which case the driver only prints an info level trace message. If a driver attempts to consume a pinctrl with pins that do not exist, core panics. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 51 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index fb661410f4f..c1e1ab31fcc 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,7 @@ * @pupd: One of GPIO_PUPD_* * @od: One of GPIO_OD_* * @af: Alternate function numerical ID between 0 and 15 + * @nsec: Hint on expected secure state of the pin: 0 if secure, 1 otherwise */ struct gpio_cfg { uint16_t mode: 2; @@ -135,6 +137,7 @@ struct gpio_cfg { uint16_t pupd: 2; uint16_t od: 1; uint16_t af: 4; + uint16_t nsec: 1; }; /* @@ -616,8 +619,10 @@ static void set_gpio_cfg(uint32_t bank_id, uint32_t pin, struct gpio_cfg *cfg) /* Count pins described in the DT node and get related data if possible */ static int get_pinctrl_from_fdt(const void *fdt, int node, + int consumer_node __maybe_unused, struct stm32_pinctrl *pinctrl, size_t count) { + struct stm32_gpio_bank *bank_ref = NULL; const fdt32_t *cuint = NULL; const fdt32_t *slewrate = NULL; int len = 0; @@ -625,6 +630,7 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, uint32_t speed = GPIO_OSPEED_LOW; uint32_t pull = GPIO_PUPD_NO_PULL; size_t found = 0; + bool do_panic = false; cuint = fdt_getprop(fdt, node, "pinmux", &len); if (!cuint) @@ -647,6 +653,7 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, uint32_t alternate = 0; uint32_t odata = 0; bool opendrain = false; + bool pin_non_secure = true; pincfg = fdt32_to_cpu(*cuint); cuint++; @@ -657,6 +664,8 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, mode = pincfg & DT_GPIO_MODE_MASK; + pin_non_secure = pincfg & STM32_PIN_NSEC; + switch (mode) { case 0: mode = GPIO_MODE_INPUT; @@ -717,11 +726,24 @@ static int get_pinctrl_from_fdt(const void *fdt, int node, ref->cfg.pupd = pull; ref->cfg.od = odata; ref->cfg.af = alternate; + ref->cfg.nsec = pin_non_secure; + + bank_ref = stm32_gpio_get_bank(bank); + + if (pin >= bank_ref->ngpios) { + EMSG("node %s requests pin %c%u that does not exist", + fdt_get_name(fdt, consumer_node, NULL), + bank + 'A', pin); + do_panic = true; + } } found++; } + if (do_panic) + panic(); + return (int)found; } @@ -1377,11 +1399,36 @@ static TEE_Result stm32_pinctrl_conf_apply(struct pinconf *conf) for (n = 0; n < pin_count; n++) { bank = stm32_gpio_get_bank(p[n].bank); + + if (!pin_is_accessible(bank, p[n].pin)) { + EMSG("Apply pinctrl for pin %c%u that cannot be accessed", + p[n].bank + 'A', p[n].pin); + error = true; + continue; + } + res = acquire_rif_semaphore_if_needed(bank, p[n].pin); if (res) { EMSG("Failed to acquire GPIO %c%u semaphore", bank->bank_id + 'A', p[n].pin); error = true; + continue; + } + + if (p[n].cfg.nsec == !pin_is_secure(bank, p[n].pin)) + continue; + + if (IS_ENABLED(CFG_INSECURE)) { + IMSG("WARNING: apply pinctrl for %ssecure pin %c%u that is %ssecure", + p[n].cfg.nsec ? "non-" : "", + p[n].bank + 'A', p[n].pin, + pin_is_secure(bank, p[n].pin) ? "" : "non-"); + } else { + EMSG("Apply pinctrl for %ssecure pin %c%u that is %ssecure", + p[n].cfg.nsec ? "non-" : "", + p[n].bank + 'A', p[n].pin, + pin_is_secure(bank, p[n].pin) ? "" : "non-"); + error = true; } } @@ -1515,7 +1562,9 @@ static TEE_Result stm32_pinctrl_dt_get(struct dt_pargs *pargs, fdt_for_each_subnode(pinmux_node, fdt, pinctrl_node) { int found = 0; - found = get_pinctrl_from_fdt(fdt, pinmux_node, pinctrl + count, + found = get_pinctrl_from_fdt(fdt, pinmux_node, + pargs->consumer_node, + pinctrl + count, pin_count - count); if (found <= 0 && found > ((int)pin_count - count)) { /* We can't recover from an error here so let's panic */ From 512faf9550f592faf3726a51ab03a80b36d6cf13 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:18:43 +0200 Subject: [PATCH 14/20] plat-stm32mp1: shared_resources: do not manage pins secure state Remove management of GPIO and pinctrl secure state since this is now handled from STM32 ETZPC driver based through the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- .../arch/arm/plat-stm32mp1/shared_resources.c | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c index b08108588d9..539ad67b7d5 100644 --- a/core/arch/arm/plat-stm32mp1/shared_resources.c +++ b/core/arch/arm/plat-stm32mp1/shared_resources.c @@ -586,28 +586,6 @@ static void rcc_secure_configuration(void) } } -static void set_gpio_secure_configuration(void) -{ - unsigned int pin = 0; - - for (pin = 0; pin < get_gpioz_nbpin(); pin++) { - enum stm32mp_shres shres = STM32MP1_SHRES_GPIOZ(pin); - bool secure = stm32mp_periph_is_secure(shres); - - stm32_gpio_set_secure_cfg(GPIO_BANK_Z, pin, secure); - } -} - -static TEE_Result gpioz_pm(enum pm_op op, uint32_t pm_hint __unused, - const struct pm_callback_handle *hdl __unused) -{ - if (op == PM_OP_RESUME) - set_gpio_secure_configuration(); - - return TEE_SUCCESS; -} -DECLARE_KEEP_PAGER(gpioz_pm); - static TEE_Result stm32mp1_init_final_shres(void) { enum stm32mp_shres id = STM32MP1_SHRES_COUNT; @@ -621,11 +599,6 @@ static TEE_Result stm32mp1_init_final_shres(void) shres2str_id(id), id, shres2str_state(*state)); } - if (IS_ENABLED(CFG_STM32_GPIO)) { - set_gpio_secure_configuration(); - register_pm_driver_cb(gpioz_pm, NULL, - "stm32mp1-shared-resources"); - } rcc_secure_configuration(); return TEE_SUCCESS; From 9874822369116b6476c6e22524d6f04ea893d0dd Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:20:33 +0200 Subject: [PATCH 15/20] drivers: stm32_i2c: remove use of stm32_pinctrl_set_secure_cfg() Remove use of stm32_pinctrl_set_secure_cfg() to set the secure state of the pins of a pinctrl state since this is now handled from STM32 GPIO driver based on the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_i2c.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/drivers/stm32_i2c.c b/core/drivers/stm32_i2c.c index 08b21c12570..e3ca041e14b 100644 --- a/core/drivers/stm32_i2c.c +++ b/core/drivers/stm32_i2c.c @@ -819,9 +819,6 @@ int stm32_i2c_init(struct i2c_handle_s *hi2c, i2c_config_analog_filter(hi2c, init_data->analog_filter); - if (IS_ENABLED(CFG_STM32MP13)) - stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); - clk_disable(hi2c->clock); if (hi2c->pinctrl && pinctrl_apply_state(hi2c->pinctrl)) @@ -1586,9 +1583,6 @@ void stm32_i2c_resume(struct i2c_handle_s *hi2c) restore_cfg(hi2c, &hi2c->sec_cfg); - if (IS_ENABLED(CFG_STM32MP13)) - stm32_pinctrl_set_secure_cfg(hi2c->pinctrl, true); - hi2c->i2c_state = I2C_STATE_READY; } From 3f69815ca7fabe6892ec6b408a61d7bb7a1ca869 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:20:46 +0200 Subject: [PATCH 16/20] drivers: stm32_uart: remove use of stm32_pinctrl_set_secure_cfg() Remove use of stm32_pinctrl_set_secure_cfg() to set the secure state of the pins of a pinctrl state since this is now handled from STM32 GPIO driver based on the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_uart.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c index f7375256fe2..d7f07d2a901 100644 --- a/core/drivers/stm32_uart.c +++ b/core/drivers/stm32_uart.c @@ -109,31 +109,23 @@ void stm32_uart_init(struct stm32_uart_pdata *pd, vaddr_t base) pd->chip.ops = &stm32_uart_serial_ops; } -static void register_secure_uart(struct stm32_uart_pdata *pd) +static void register_secure_uart(struct stm32_uart_pdata *pd __maybe_unused) { #ifndef CFG_STM32MP25 stm32mp_register_secure_periph_iomem(pd->base.pa); stm32mp_register_secure_pinctrl(pd->pinctrl); if (pd->pinctrl_sleep) stm32mp_register_secure_pinctrl(pd->pinctrl_sleep); -#else - stm32_pinctrl_set_secure_cfg(pd->pinctrl, true); - if (pd->pinctrl_sleep) - stm32_pinctrl_set_secure_cfg(pd->pinctrl, true); #endif } -static void register_non_secure_uart(struct stm32_uart_pdata *pd) +static void register_non_secure_uart(struct stm32_uart_pdata *pd __maybe_unused) { #ifndef CFG_STM32MP25 stm32mp_register_non_secure_periph_iomem(pd->base.pa); stm32mp_register_non_secure_pinctrl(pd->pinctrl); if (pd->pinctrl_sleep) stm32mp_register_non_secure_pinctrl(pd->pinctrl_sleep); -#else - stm32_pinctrl_set_secure_cfg(pd->pinctrl, false); - if (pd->pinctrl_sleep) - stm32_pinctrl_set_secure_cfg(pd->pinctrl, false); #endif } From 83bf7e3ca18e67cf5e2db95b20e345ddbbc93169 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:31:04 +0200 Subject: [PATCH 17/20] drivers: stm32_uart: remove use of shared_resource for pinctlr Remove use of shared_resources platform driver to manage the secure state of the pins of a pinctrl state since this is now managed using the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_uart.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c index d7f07d2a901..e85df6823d9 100644 --- a/core/drivers/stm32_uart.c +++ b/core/drivers/stm32_uart.c @@ -113,9 +113,6 @@ static void register_secure_uart(struct stm32_uart_pdata *pd __maybe_unused) { #ifndef CFG_STM32MP25 stm32mp_register_secure_periph_iomem(pd->base.pa); - stm32mp_register_secure_pinctrl(pd->pinctrl); - if (pd->pinctrl_sleep) - stm32mp_register_secure_pinctrl(pd->pinctrl_sleep); #endif } @@ -123,9 +120,6 @@ static void register_non_secure_uart(struct stm32_uart_pdata *pd __maybe_unused) { #ifndef CFG_STM32MP25 stm32mp_register_non_secure_periph_iomem(pd->base.pa); - stm32mp_register_non_secure_pinctrl(pd->pinctrl); - if (pd->pinctrl_sleep) - stm32mp_register_non_secure_pinctrl(pd->pinctrl_sleep); #endif } From cb731cf0b2c68da82ef38e0f4b59a7aa48601615 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:31:47 +0200 Subject: [PATCH 18/20] plat-stm32mp1: stm32mp1_stpmic: remove use of shared_resource for pinctrl Remove use of shared_resources platform driver in STM32MP15 PMIC driver to manage the secure state of the pins of a pinctrl state since this is now managed using the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c index 7cb510fc3a6..fad43bb2b96 100644 --- a/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c +++ b/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pmic.c @@ -676,19 +676,11 @@ static void register_non_secure_pmic(void) if (!i2c_handle->base.pa) return; - stm32mp_register_non_secure_pinctrl(i2c_handle->pinctrl); - if (i2c_handle->pinctrl_sleep) - stm32mp_register_non_secure_pinctrl(i2c_handle->pinctrl_sleep); - stm32mp_register_non_secure_periph_iomem(i2c_handle->base.pa); } static void register_secure_pmic(void) { - stm32mp_register_secure_pinctrl(i2c_handle->pinctrl); - if (i2c_handle->pinctrl_sleep) - stm32mp_register_secure_pinctrl(i2c_handle->pinctrl_sleep); - stm32mp_register_secure_periph_iomem(i2c_handle->base.pa); register_pm_driver_cb(pmic_pm, NULL, "stm32mp1-pmic"); } From ec8b8d64fe984328e7139a526beeb95385b19348 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 4 Jul 2024 11:10:08 +0200 Subject: [PATCH 19/20] drivers: stm32_gpio: remove gpio/pinctrl API function to set secure state Remove stm32_gpio_set_secure_cfg() and stm32_pinctrl_set_secure_cfg() functions that are no more used since the STM32 GPIO and pins secure configurations are managed only through the firewall framework facilities. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- core/drivers/stm32_gpio.c | 42 ------------------------------- core/include/drivers/stm32_gpio.h | 24 ------------------ 2 files changed, 66 deletions(-) diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index c1e1ab31fcc..03d0e1d95f9 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -1367,25 +1367,6 @@ static TEE_Result dt_stm32_gpio_pinctrl(const void *fdt, int node, return TEE_SUCCESS; } -void stm32_gpio_set_secure_cfg(unsigned int bank_id, unsigned int pin, - bool secure) -{ - struct stm32_gpio_bank *bank = stm32_gpio_get_bank(bank_id); - uint32_t exceptions = 0; - - if (clk_enable(bank->clock)) - panic(); - exceptions = cpu_spin_lock_xsave(&gpio_lock); - - if (secure) - io_setbits32(bank->base + GPIO_SECR_OFFSET, BIT(pin)); - else - io_clrbits32(bank->base + GPIO_SECR_OFFSET, BIT(pin)); - - cpu_spin_unlock_xrestore(&gpio_lock, exceptions); - clk_disable(bank->clock); -} - #ifdef CFG_DRIVERS_PINCTRL static TEE_Result stm32_pinctrl_conf_apply(struct pinconf *conf) { @@ -1496,29 +1477,6 @@ void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, *count = pin_count; } -void stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl, bool secure) -{ - size_t conf_index = 0; - - if (!pinctrl) - return; - - for (conf_index = 0; conf_index < pinctrl->conf_count; conf_index++) { - struct pinconf *pinconf = pinctrl->confs[conf_index]; - struct stm32_pinctrl_array *ref = pinconf->priv; - struct stm32_pinctrl *pc = NULL; - size_t n = 0; - - for (n = 0; n < ref->count; n++) { - if (pinconf->ops != &stm32_pinctrl_ops) - continue; - - pc = ref->pinctrl + n; - stm32_gpio_set_secure_cfg(pc->bank, pc->pin, secure); - } - } -} - /* Allocate and return a pinctrl configuration from a DT reference */ static TEE_Result stm32_pinctrl_dt_get(struct dt_pargs *pargs, void *data __unused, diff --git a/core/include/drivers/stm32_gpio.h b/core/include/drivers/stm32_gpio.h index 883888171f3..21660d52492 100644 --- a/core/include/drivers/stm32_gpio.h +++ b/core/include/drivers/stm32_gpio.h @@ -16,24 +16,6 @@ struct pinctrl_state; struct stm32_pinctrl; #ifdef CFG_STM32_GPIO -/* - * Configure pin muxing access permission: can be secure or not - * - * @bank: GPIO bank identifier as assigned by the platform - * @pin: Pin number in the GPIO bank - * @secure: True if pin is secure, false otherwise - */ -void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, - bool secure); - -/* - * Configure pin muxing access permission: can be secure or not - * - * @pinctrl: Pin control state where STM32_GPIO pin are to configure - * @secure: True if pin is secure, false otherwise - */ -void stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl, bool secure); - /* * Get the bank and pin indices related to a pin control state * @pinctrl: Pinctrl state @@ -45,12 +27,6 @@ void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *pinctrl, unsigned int *bank, unsigned int *pin, unsigned int *count); #else -static inline void -stm32_pinctrl_set_secure_cfg(struct pinctrl_state *pinctrl __unused, - bool secure __unused) -{ -} - static inline void stm32_gpio_pinctrl_bank_pin(struct pinctrl_state *p __unused, unsigned int *bank __unused, unsigned int *pin __unused, From b2a5f61a3a75eaaabb7fb7c4caed29b211c4ae08 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Wed, 23 Oct 2024 16:32:54 +0200 Subject: [PATCH 20/20] plat-stm32mp1: shared_resources: remove pin/GPIO secure state management Remove the pin and GPIO secure state management from shared_resources platform driver since this is now managed using the firewall framework. Signed-off-by: Etienne Carriere Reviewed-by: Gatien Chevallier --- .../arch/arm/plat-stm32mp1/shared_resources.c | 140 +----------------- core/arch/arm/plat-stm32mp1/stm32_util.h | 71 --------- core/drivers/stm32_gpio.c | 3 - 3 files changed, 5 insertions(+), 209 deletions(-) diff --git a/core/arch/arm/plat-stm32mp1/shared_resources.c b/core/arch/arm/plat-stm32mp1/shared_resources.c index 539ad67b7d5..3523e043069 100644 --- a/core/arch/arm/plat-stm32mp1/shared_resources.c +++ b/core/arch/arm/plat-stm32mp1/shared_resources.c @@ -131,25 +131,6 @@ static __maybe_unused const char *shres2str_state(enum shres_state id) return shres2str_state_tbl[id]; } -/* GPIOZ bank pin count depends on SoC variants */ -/* A light count routine for unpaged context to not depend on DTB support */ -static int gpioz_nbpin = -1; - -static unsigned int get_gpioz_nbpin(void) -{ - if (gpioz_nbpin < 0) - panic(); - - return gpioz_nbpin; -} - -void stm32mp_register_gpioz_pin_count(size_t count) -{ - assert(gpioz_nbpin == -1); - - gpioz_nbpin = count; -} - static void register_periph(enum stm32mp_shres id, enum shres_state state) { assert(id < STM32MP1_SHRES_COUNT && @@ -180,11 +161,7 @@ static void register_periph(enum stm32mp_shres id, enum shres_state state) case STM32MP1_SHRES_GPIOZ(5): case STM32MP1_SHRES_GPIOZ(6): case STM32MP1_SHRES_GPIOZ(7): - if ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin()) { - EMSG("Invalid GPIO %u >= %u", - id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin()); - panic(); - } + panic("Deprecated registering of GPIOZ resources"); break; case STM32MP1_SHRES_PLL3: panic("Deprecated registering of PLL3 resources"); @@ -266,7 +243,8 @@ static void register_periph_iomem(vaddr_t base, enum shres_state state) case GPIOI_BASE: case GPIOJ_BASE: case GPIOK_BASE: - fallthrough; + panic("Deprecated registering of GPIOz resources"); + break; #endif #ifdef CFG_WITH_NSEC_UARTS case USART2_BASE: @@ -308,80 +286,6 @@ void stm32mp_register_non_secure_periph_iomem(vaddr_t base) register_periph_iomem(base, SHRES_NON_SECURE); } -/* Register GPIO resource */ -void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin) -{ - switch (bank) { - case GPIO_BANK_Z: - assert(pin < get_gpioz_nbpin()); - register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_SECURE); - break; - default: - EMSG("GPIO bank %u cannot be secured", bank); - panic(); - } -} - -void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin) -{ - switch (bank) { - case GPIO_BANK_Z: - assert(pin < get_gpioz_nbpin()); - register_periph(STM32MP1_SHRES_GPIOZ(pin), SHRES_NON_SECURE); - break; - default: - break; - } -} - -void stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl) -{ - unsigned int *bank = NULL; - unsigned int *pin = NULL; - size_t count = 0; - size_t n = 0; - - stm32_gpio_pinctrl_bank_pin(pinctrl, NULL, NULL, &count); - if (!count) - return; - - bank = calloc(count, sizeof(*bank)); - pin = calloc(count, sizeof(*pin)); - if (!bank || !pin) - panic(); - - stm32_gpio_pinctrl_bank_pin(pinctrl, bank, pin, &count); - for (n = 0; n < count; n++) - stm32mp_register_secure_gpio(bank[n], pin[n]); - - free(bank); - free(pin); -} - -void stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl) -{ - unsigned int *bank = NULL; - unsigned int *pin = NULL; - size_t count = 0; - size_t n = 0; - - stm32_gpio_pinctrl_bank_pin(pinctrl, NULL, NULL, &count); - if (!count) - return; - - bank = calloc(count, sizeof(*bank)); - pin = calloc(count, sizeof(*pin)); - if (!bank || !pin) - panic(); - - stm32_gpio_pinctrl_bank_pin(pinctrl, bank, pin, &count); - for (n = 0; n < count; n++) - stm32mp_register_non_secure_gpio(bank[n], pin[n]); - - free(bank); - free(pin); -} - static void lock_registering(void) { registering_locked = true; @@ -394,40 +298,6 @@ bool stm32mp_periph_is_secure(enum stm32mp_shres id) return shres_state[id] == SHRES_SECURE; } -bool stm32mp_gpio_bank_is_non_secure(unsigned int bank) -{ - unsigned int not_secure = 0; - unsigned int pin = 0; - - lock_registering(); - - if (bank != GPIO_BANK_Z) - return true; - - for (pin = 0; pin < get_gpioz_nbpin(); pin++) - if (!stm32mp_periph_is_secure(STM32MP1_SHRES_GPIOZ(pin))) - not_secure++; - - return not_secure > 0 && not_secure == get_gpioz_nbpin(); -} - -bool stm32mp_gpio_bank_is_secure(unsigned int bank) -{ - unsigned int secure = 0; - unsigned int pin = 0; - - lock_registering(); - - if (bank != GPIO_BANK_Z) - return false; - - for (pin = 0; pin < get_gpioz_nbpin(); pin++) - if (stm32mp_periph_is_secure(STM32MP1_SHRES_GPIOZ(pin))) - secure++; - - return secure > 0 && secure == get_gpioz_nbpin(); -} - bool stm32mp_nsec_can_access_clock(unsigned long clock_id) { enum stm32mp_shres shres_id = STM32MP1_SHRES_COUNT; @@ -459,7 +329,7 @@ bool stm32mp_nsec_can_access_clock(unsigned long clock_id) case BSEC: return true; case GPIOZ: - return !stm32mp_gpio_bank_is_secure(GPIO_BANK_Z); + return true; case SPI6_K: shres_id = STM32MP1_SHRES_SPI6; break; @@ -503,7 +373,7 @@ bool stm32mp_nsec_can_access_reset(unsigned int reset_id) switch (reset_id) { case GPIOZ_R: - return stm32mp_gpio_bank_is_non_secure(GPIO_BANK_Z); + return false; case SPI6_R: shres_id = STM32MP1_SHRES_SPI6; break; diff --git a/core/arch/arm/plat-stm32mp1/stm32_util.h b/core/arch/arm/plat-stm32mp1/stm32_util.h index 68fe0a8dd95..6b69ef1260e 100644 --- a/core/arch/arm/plat-stm32mp1/stm32_util.h +++ b/core/arch/arm/plat-stm32mp1/stm32_util.h @@ -235,46 +235,9 @@ void stm32mp_register_secure_periph_iomem(vaddr_t base); */ void stm32mp_register_non_secure_periph_iomem(vaddr_t base); -/* - * Register GPIO resource as a secure peripheral - * @bank: Bank of the target GPIO - * @pin: Bit position of the target GPIO in the bank - */ -void stm32mp_register_secure_gpio(unsigned int bank, unsigned int pin); - -/* - * Register GPIO resource as a non-secure peripheral - * @bank: Bank of the target GPIO - * @pin: Bit position of the target GPIO in the bank - */ -void stm32mp_register_non_secure_gpio(unsigned int bank, unsigned int pin); - -/* - * Register pin resource of a pin control state as a secure peripheral - * @bank: Bank of the target GPIO - * @pin: Bit position of the target GPIO in the bank - */ -void stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl); - -/* - * Register pin resource of a pin control state as a non-secure peripheral - * @bank: Bank of the target GPIO - * @pin: Bit position of the target GPIO in the bank - */ -void stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl); - /* Return true if and only if resource @id is registered as secure */ bool stm32mp_periph_is_secure(enum stm32mp_shres id); -/* Return true if and only if GPIO bank @bank is registered as secure */ -bool stm32mp_gpio_bank_is_secure(unsigned int bank); - -/* Return true if and only if GPIO bank @bank is registered as non-secure */ -bool stm32mp_gpio_bank_is_non_secure(unsigned int bank); - -/* Register number of pins in the GPIOZ bank */ -void stm32mp_register_gpioz_pin_count(size_t count); - #else /* CFG_STM32MP1_SHARED_RESOURCES */ static inline void stm32mp_register_secure_periph(enum stm32mp_shres id @@ -296,43 +259,9 @@ static inline void stm32mp_register_non_secure_periph_iomem(vaddr_t base { } -static inline void stm32mp_register_secure_gpio(unsigned int bank __unused, - unsigned int pin __unused) -{ -} - -static inline void stm32mp_register_non_secure_gpio(unsigned int bank __unused, - unsigned int pin __unused) -{ -} - -static inline void -stm32mp_register_secure_pinctrl(struct pinctrl_state *pinctrl __unused) -{ -} - -static inline void -stm32mp_register_non_secure_pinctrl(struct pinctrl_state *pinctrl __unused) -{ -} - static inline bool stm32mp_periph_is_secure(enum stm32mp_shres id __unused) { return true; } - -static inline bool stm32mp_gpio_bank_is_secure(unsigned int bank __unused) -{ - return true; -} - -static inline bool stm32mp_gpio_bank_is_non_secure(unsigned int bank __unused) -{ - return false; -} - -static inline void stm32mp_register_gpioz_pin_count(size_t count __unused) -{ -} #endif /* CFG_STM32MP1_SHARED_RESOURCES */ #endif /*__STM32_UTIL_H__*/ diff --git a/core/drivers/stm32_gpio.c b/core/drivers/stm32_gpio.c index 03d0e1d95f9..cebb9344c5e 100644 --- a/core/drivers/stm32_gpio.c +++ b/core/drivers/stm32_gpio.c @@ -1266,9 +1266,6 @@ static TEE_Result dt_stm32_gpio_bank(const void *fdt, int node, bank->base = io_pa_or_va_nsec(&pa_va, blen); } - if (compat->gpioz) - stm32mp_register_gpioz_pin_count(bank->ngpios); - *out_bank = bank; return TEE_SUCCESS;