From: Fabien Dessenne <[email protected]> The hardware denies any access from the U-Boot non-secure world to the secure-protected pins. Hence, prevent any driver to configure such a pin. Identify the secure pins with "NO ACCESS" through the 'pinmux status -a' command. Use a driver data structure to identify which hardware versions support this feature.
Signed-off-by: Fabien Dessenne <[email protected]> Signed-off-by: Patrice Chotard <[email protected]> --- drivers/pinctrl/pinctrl_stm32.c | 83 +++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index fbf0271f08a..1758f9a909c 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -11,6 +11,7 @@ #include <malloc.h> #include <asm/gpio.h> #include <asm/io.h> +#include <dm/device-internal.h> #include <dm/device_compat.h> #include <dm/lists.h> #include <dm/pinctrl.h> @@ -27,6 +28,7 @@ #define PUPD_MASK 3 #define OTYPE_MSK 1 #define AFR_MASK 0xF +#define SECCFG_MSK 1 struct stm32_pinctrl_priv { struct hwspinlock hws; @@ -39,7 +41,12 @@ struct stm32_gpio_bank { struct list_head list; }; +struct stm32_pinctrl_data { + bool secure_control; +}; + #ifndef CONFIG_XPL_BUILD +static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx); static char pin_name[PINNAME_SIZE]; static const char * const pinmux_mode[GPIOF_COUNT] = { @@ -216,6 +223,12 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, if (!gpio_dev) return -ENODEV; + /* Check access protection */ + if (stm32_pinctrl_get_access(gpio_dev, gpio_idx)) { + snprintf(buf, size, "NO ACCESS"); + return 0; + } + mode = gpio_get_raw_function(gpio_dev, gpio_idx, &label); dev_dbg(dev, "selector = %d gpio_idx = %d mode = %d\n", selector, gpio_idx, mode); @@ -252,6 +265,20 @@ static int stm32_pinctrl_get_pin_muxing(struct udevice *dev, #endif +static int stm32_pinctrl_get_access(struct udevice *gpio_dev, unsigned int gpio_idx) +{ + struct stm32_gpio_priv *priv = dev_get_priv(gpio_dev); + struct stm32_gpio_regs *regs = priv->regs; + ulong drv_data = dev_get_driver_data(gpio_dev); + + /* Deny request access if IO is secured */ + if ((drv_data & STM32_GPIO_FLAG_SEC_CTRL) && + ((readl(®s->seccfgr) >> gpio_idx) & SECCFG_MSK)) + return -EACCES; + + return 0; +} + static int stm32_pinctrl_probe(struct udevice *dev) { struct stm32_pinctrl_priv *priv = dev_get_priv(dev); @@ -279,6 +306,14 @@ static int stm32_gpio_config(ofnode node, int ret; u32 index; + /* Check access protection */ + ret = stm32_pinctrl_get_access(desc->dev, desc->offset); + if (ret) { + dev_err(desc->dev, "Failed to get secure IO %s %d @ %p\n", + uc_priv->bank_name, desc->offset, regs); + return ret; + } + if (!ctl || ctl->af > 15 || ctl->mode > 3 || ctl->otype > 1 || ctl->pupd > 2 || ctl->speed > 3) return -EINVAL; @@ -414,8 +449,25 @@ static int stm32_pinctrl_bind(struct udevice *dev) { ofnode node; const char *name; + struct driver *drv; + const struct stm32_pinctrl_data *drv_data; + ulong gpio_data = 0; int ret; + drv = lists_driver_lookup_name("gpio_stm32"); + if (!drv) { + debug("Cannot find driver 'gpio_stm32'\n"); + return -ENOENT; + } + + drv_data = (const struct stm32_pinctrl_data *)dev_get_driver_data(dev); + if (!drv_data) { + debug("Cannot find driver data\n"); + return -EINVAL; + } + if (drv_data->secure_control) + gpio_data = STM32_GPIO_FLAG_SEC_CTRL; + dev_for_each_subnode(node, dev) { dev_dbg(dev, "bind %s\n", ofnode_get_name(node)); @@ -431,8 +483,7 @@ static int stm32_pinctrl_bind(struct udevice *dev) return -EINVAL; /* Bind each gpio node */ - ret = device_bind_driver_to_node(dev, "gpio_stm32", - name, node, NULL); + ret = device_bind_with_driver_data(dev, drv, name, gpio_data, node, NULL); if (ret) return ret; @@ -495,17 +546,25 @@ static struct pinctrl_ops stm32_pinctrl_ops = { #endif }; +static const struct stm32_pinctrl_data stm32_pinctrl_no_sec = { + .secure_control = false, +}; + +static const struct stm32_pinctrl_data stm32_pinctrl_with_sec = { + .secure_control = true, +}; + static const struct udevice_id stm32_pinctrl_ids[] = { - { .compatible = "st,stm32f429-pinctrl" }, - { .compatible = "st,stm32f469-pinctrl" }, - { .compatible = "st,stm32f746-pinctrl" }, - { .compatible = "st,stm32f769-pinctrl" }, - { .compatible = "st,stm32h743-pinctrl" }, - { .compatible = "st,stm32mp157-pinctrl" }, - { .compatible = "st,stm32mp157-z-pinctrl" }, - { .compatible = "st,stm32mp135-pinctrl" }, - { .compatible = "st,stm32mp257-pinctrl" }, - { .compatible = "st,stm32mp257-z-pinctrl" }, + { .compatible = "st,stm32f429-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f469-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f746-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32f769-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32h743-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp157-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp157-z-pinctrl", .data = (ulong)&stm32_pinctrl_no_sec }, + { .compatible = "st,stm32mp135-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, + { .compatible = "st,stm32mp257-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, + { .compatible = "st,stm32mp257-z-pinctrl", .data = (ulong)&stm32_pinctrl_with_sec }, { } }; -- 2.43.0

