mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
pinctrl: pinctrl_stm32: prevent the use of the secure protected pins
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 <fabien.dessenne@foss.st.com> Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
This commit is contained in:
committed by
Patrice Chotard
parent
7accb716c1
commit
04dcaadd43
@@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user