2020-04-20 16:38:42

by Benjamin GAIGNARD

[permalink] [raw]
Subject: [PATCH 0/5] STM32 ETZPC bus controller

STM32 Extended TrustZone Protection controller act like a firewall on the
platform bus. Depending of its configuration devices could be accessible
by the TrustZone, the co-processor or the non-secure world. ETZPC
configuration could evolve at runtime for example to switch a device from
non-secure world to co-processor.

The series introduce 'firewall' helpers to handle the new devices-tree
properties. These properties are not dedicated to ETZPC and will be reused
for STM32 next generation of bus controller.

Benjamin Gaignard (5):
dt-bindings: bus: Add firewall bindings
bus: stm32: Introduce firewall controller helpers
dt-bindings: bus: Add STM32 ETZPC firewall controller
bus: stm32: Add stm32 ETZPC firewall bus controller
ARM: dts: stm32: Use ETZPC firewall bus

.../bindings/bus/stm32/firewall-consumer.yaml | 25 ++
.../bindings/bus/stm32/firewall-provider.yaml | 18 ++
.../bindings/bus/stm32/st,stm32-etzpc.yaml | 46 ++++
arch/arm/boot/dts/stm32mp151.dtsi | 7 +-
drivers/bus/Kconfig | 2 +
drivers/bus/Makefile | 2 +
drivers/bus/stm32/Kconfig | 11 +
drivers/bus/stm32/Makefile | 2 +
drivers/bus/stm32/firewall.c | 266 +++++++++++++++++++++
drivers/bus/stm32/firewall.h | 75 ++++++
drivers/bus/stm32/stm32-etzpc.c | 160 +++++++++++++
include/dt-bindings/bus/stm32/stm32-etzpc.h | 90 +++++++
12 files changed, 702 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/bus/stm32/firewall-consumer.yaml
create mode 100644 Documentation/devicetree/bindings/bus/stm32/firewall-provider.yaml
create mode 100644 Documentation/devicetree/bindings/bus/stm32/st,stm32-etzpc.yaml
create mode 100644 drivers/bus/stm32/Kconfig
create mode 100644 drivers/bus/stm32/Makefile
create mode 100644 drivers/bus/stm32/firewall.c
create mode 100644 drivers/bus/stm32/firewall.h
create mode 100644 drivers/bus/stm32/stm32-etzpc.c
create mode 100644 include/dt-bindings/bus/stm32/stm32-etzpc.h

--
2.15.0


2020-04-20 16:38:46

by Benjamin GAIGNARD

[permalink] [raw]
Subject: [PATCH 1/5] dt-bindings: bus: Add firewall bindings

Add schemas for firewall consumer and provider.

Signed-off-by: Benjamin Gaignard <[email protected]>
---
.../bindings/bus/stm32/firewall-consumer.yaml | 25 ++++++++++++++++++++++
.../bindings/bus/stm32/firewall-provider.yaml | 18 ++++++++++++++++
2 files changed, 43 insertions(+)
create mode 100644 Documentation/devicetree/bindings/bus/stm32/firewall-consumer.yaml
create mode 100644 Documentation/devicetree/bindings/bus/stm32/firewall-provider.yaml

diff --git a/Documentation/devicetree/bindings/bus/stm32/firewall-consumer.yaml b/Documentation/devicetree/bindings/bus/stm32/firewall-consumer.yaml
new file mode 100644
index 000000000000..8f123888d058
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/stm32/firewall-consumer.yaml
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/stm32/firewall-consumer.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common Bus Firewall consumer binding
+
+maintainers:
+ - Benjamin Gaignard <[email protected]>
+
+# always select the core schema
+select: true
+
+properties:
+ firewall-0: true
+
+ firewall-names: true
+
+patternProperties:
+ "firewall-[0-9]":
+ $ref: "/schemas/types.yaml#/definitions/phandle-array"
+
+dependencies:
+ firewall-names: [ firewall-0 ]
diff --git a/Documentation/devicetree/bindings/bus/stm32/firewall-provider.yaml b/Documentation/devicetree/bindings/bus/stm32/firewall-provider.yaml
new file mode 100644
index 000000000000..299824c620ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/stm32/firewall-provider.yaml
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/stm32/firewall-provider.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common Bus Firewall provider binding
+
+maintainers:
+ - Benjamin Gaignard <[email protected]>
+
+properties:
+ '#firewall-cells':
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of cells in a bus firewall specifier
+
+required:
+ - '#firewall-cells'
--
2.15.0

2020-04-20 16:38:50

by Benjamin GAIGNARD

[permalink] [raw]
Subject: [PATCH 4/5] bus: stm32: Add stm32 ETZPC firewall bus controller

Add STM32 Extended TrustZone Protection bus controller.
For each of device-tree nodes it will check and apply
firewall configuration. If it doesn't match the device
will not be probed by platform bus.

A device could be configured to be accessible by trusted world,
co-processor or non-secure world.

Signed-off-by: Benjamin Gaignard <[email protected]>
---
drivers/bus/stm32/Kconfig | 8 ++
drivers/bus/stm32/Makefile | 1 +
drivers/bus/stm32/stm32-etzpc.c | 160 ++++++++++++++++++++++++++++
include/dt-bindings/bus/stm32/stm32-etzpc.h | 90 ++++++++++++++++
4 files changed, 259 insertions(+)
create mode 100644 drivers/bus/stm32/stm32-etzpc.c
create mode 100644 include/dt-bindings/bus/stm32/stm32-etzpc.h

diff --git a/drivers/bus/stm32/Kconfig b/drivers/bus/stm32/Kconfig
index 57221e833e2d..5dc6e2504de5 100644
--- a/drivers/bus/stm32/Kconfig
+++ b/drivers/bus/stm32/Kconfig
@@ -1,3 +1,11 @@
config FIREWALL_CONTROLLERS
bool "Support of bus firewall controllers"
depends on OF
+
+config STM32_ETZPC
+ bool "STM32 ETZPC bus controller"
+ depends on MACH_STM32MP157
+ select FIREWALL_CONTROLLERS
+ help
+ Select y to enable STM32 Extended TrustZone Protection
+ Controller (ETZPC)
diff --git a/drivers/bus/stm32/Makefile b/drivers/bus/stm32/Makefile
index eb6b978d6450..d42e99b5865e 100644
--- a/drivers/bus/stm32/Makefile
+++ b/drivers/bus/stm32/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_FIREWALL_CONTROLLERS) += firewall.o
+obj-$(CONFIG_STM32_ETZPC) += stm32-etzpc.o
diff --git a/drivers/bus/stm32/stm32-etzpc.c b/drivers/bus/stm32/stm32-etzpc.c
new file mode 100644
index 000000000000..c216c71448ed
--- /dev/null
+++ b/drivers/bus/stm32/stm32-etzpc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved
+ * Author: Benjamin Gaignard <[email protected]> for STMicroelectronics.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/bus/stm32/stm32-etzpc.h>
+
+#include "firewall.h"
+
+#define ETZPC_DECPROT 0x010
+#define ETZPC_NUM_LOCKS 94
+
+struct stm32_etzpc {
+ struct regmap_field *fields[ETZPC_NUM_LOCKS];
+};
+
+static int stm32_etzpc_set_config(void *priv, struct of_phandle_args *out_args)
+{
+ struct stm32_etzpc *etzpc = dev_get_drvdata((struct device *)priv);
+ int index = out_args->args[0];
+ unsigned int value = out_args->args[1];
+ u32 status;
+
+ if (out_args->args_count != 2)
+ return -EINVAL;
+
+ if (index >= ETZPC_NUM_LOCKS)
+ return -EINVAL;
+
+ if (value > STM32_ETZPC_NON_SECURE)
+ return -EINVAL;
+
+ regmap_field_force_write(etzpc->fields[index], value);
+
+ /* Hardware could denied the new value, read it back to check it */
+ regmap_field_read(etzpc->fields[index], &status);
+
+ if (value != status) {
+ pr_info("failed to set configuration: index %d, value %d\n",
+ index, value);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct firewall_ops stm32_etzpc_ops = {
+ .set_config = stm32_etzpc_set_config,
+};
+
+static const struct regmap_config stm32_etzpc_regmap_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = sizeof(u32),
+ .max_register = 0x3FF,
+};
+
+static void stm32_etzpc_populate(struct device *parent)
+{
+ struct device_node *child;
+
+ if (!parent)
+ return;
+
+ for_each_available_child_of_node(dev_of_node(parent), child) {
+ if (firewall_set_default_config(child)) {
+ /*
+ * Failed to set firewall configuration mark the node
+ * as populated so platform bus won't probe it
+ */
+ of_node_set_flag(child, OF_POPULATED);
+ dev_info(parent, "%s: Bad firewall configuration\n",
+ child->name);
+ }
+ }
+}
+
+static int stm32_etzpc_probe(struct platform_device *pdev)
+{
+ struct stm32_etzpc *etzpc;
+ struct regmap *regmap;
+ struct resource *res;
+ void __iomem *mmio;
+ int i, ret;
+
+ etzpc = devm_kzalloc(&pdev->dev, sizeof(*etzpc), GFP_KERNEL);
+ if (!etzpc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
+
+ regmap = devm_regmap_init_mmio(&pdev->dev, mmio,
+ &stm32_etzpc_regmap_cfg);
+
+ for (i = 0; i < ETZPC_NUM_LOCKS; i++) {
+ struct reg_field field;
+
+ /*
+ * Each hardware block status is defined by
+ * a 2 bits field and all of them are packed into
+ * 32 bits registers. Do some computation to get
+ * register offset and the shift.
+ */
+ field.reg = ETZPC_DECPROT + (i >> 4) * sizeof(u32);
+ field.lsb = (i % 0x10) << 1;
+ field.msb = field.lsb + 1;
+
+ etzpc->fields[i] = devm_regmap_field_alloc(&pdev->dev,
+ regmap, field);
+ }
+
+ platform_set_drvdata(pdev, etzpc);
+
+ ret = firewall_register(dev_of_node(&pdev->dev),
+ &stm32_etzpc_ops,
+ &pdev->dev);
+ if (ret)
+ return ret;
+
+ stm32_etzpc_populate(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id stm32_etzpc_of_match[] = {
+ { .compatible = "st,stm32-etzpc-bus" },
+ { /* end node */ }
+};
+MODULE_DEVICE_TABLE(of, stm32_etzpc_of_match);
+
+static struct platform_driver stm32_etzpc_driver = {
+ .probe = stm32_etzpc_probe,
+ .driver = {
+ .name = "stm32-etzpc",
+ .of_match_table = stm32_etzpc_of_match,
+ },
+};
+
+static int __init stm32_etzpc_init(void)
+{
+ return platform_driver_register(&stm32_etzpc_driver);
+}
+arch_initcall(stm32_etzpc_init);
+
+MODULE_AUTHOR("Benjamin Gaignard <[email protected]>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 Bus Firewall Controller");
diff --git a/include/dt-bindings/bus/stm32/stm32-etzpc.h b/include/dt-bindings/bus/stm32/stm32-etzpc.h
new file mode 100644
index 000000000000..9c4783b9783c
--- /dev/null
+++ b/include/dt-bindings/bus/stm32/stm32-etzpc.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) STMicroelectronics 2020 - All Rights Reserved
+ * Author: Benjamin Gaignard <[email protected]> for STMicroelectronics.
+ */
+
+#ifndef _STM32_ETZPC_H_
+#define _STM32_ETZPC_H_
+
+/* ETZPC configurations: trust-zone, non-secure or coprocessor*/
+#define STM32_ETZPC_TRUST 1
+#define STM32_ETPCZ_COPRO 2
+#define STM32_ETZPC_NON_SECURE 3
+
+/* ETZPC hard blocks index */
+#define STM32_ETZPC_USART1 3
+#define STM32_ETZPC_SPI6 4
+#define STM32_ETZPC_I2C4 5
+#define STM32_ETZPC_RNG1 7
+#define STM32_ETZPC_HASH1 8
+#define STM32_ETZPC_CRYP1 9
+#define STM32_ETZPC_I2C6 12
+#define STM32_ETZPC_TIM2 16
+#define STM32_ETZPC_TIM3 17
+#define STM32_ETZPC_TIM4 18
+#define STM32_ETZPC_TIM5 19
+#define STM32_ETZPC_TIM6 20
+#define STM32_ETZPC_TIM7 21
+#define STM32_ETZPC_TIM12 22
+#define STM32_ETZPC_TIM13 23
+#define STM32_ETZPC_TIM14 24
+#define STM32_ETZPC_LPTIM1 25
+#define STM32_ETZPC_SPI2 27
+#define STM32_ETZPC_SPI3 28
+#define STM32_ETZPC_USART2 30
+#define STM32_ETZPC_USART3 31
+#define STM32_ETZPC_USART4 32
+#define STM32_ETZPC_USART5 33
+#define STM32_ETZPC_I2C1 34
+#define STM32_ETZPC_I2C2 35
+#define STM32_ETZPC_I2C3 36
+#define STM32_ETZPC_I2C5 37
+#define STM32_ETZPC_CEC 38
+#define STM32_ETZPC_DAC 39
+#define STM32_ETZPC_UART7 40
+#define STM32_ETZPC_UART8 41
+#define STM32_ETZPC_MDIOS 44
+#define STM32_ETZPC_TIM1 48
+#define STM32_ETZPC_TIM8 49
+#define STM32_ETZPC_USART6 51
+#define STM32_ETZPC_SPI1 52
+#define STM32_ETZPC_SPI4 53
+#define STM32_ETZPC_TIM15 54
+#define STM32_ETZPC_TIM16 55
+#define STM32_ETZPC_TIM17 56
+#define STM32_ETZPC_SPI5 57
+#define STM32_ETZPC_SAI1 58
+#define STM32_ETZPC_SAI2 59
+#define STM32_ETZPC_SAI3 60
+#define STM32_ETZPC_DFSDM 61
+#define STM32_ETZPC_TT_FDCAN 62
+#define STM32_ETZPC_LPTIM2 64
+#define STM32_ETZPC_LPTIM3 65
+#define STM32_ETZPC_LPTIM4 66
+#define STM32_ETZPC_LPTIM5 67
+#define STM32_ETZPC_SAI4 68
+#define STM32_ETZPC_VREFBUF 69
+#define STM32_ETZPC_DCMI 70
+#define STM32_ETZPC_CRC2 71
+#define STM32_ETZPC_ADC 72
+#define STM32_ETZPC_HASH2 73
+#define STM32_ETZPC_RNG2 74
+#define STM32_ETZPC_CRYP2 75
+#define STM32_ETZPC_SRAM1 80
+#define STM32_ETZPC_SRAM2 81
+#define STM32_ETZPC_SRAM3 82
+#define STM32_ETZPC_SRAM4 83
+#define STM32_ETZPC_RETRAM 84
+#define STM32_ETZPC_OTG 85
+#define STM32_ETZPC_SDMMC3 86
+#define STM32_ETZPC_DLYBSD3 87
+#define STM32_ETZPC_DMA1 88
+#define STM32_ETZPC_DMA2 89
+#define STM32_ETZPC_DMAMUX 90
+#define STM32_ETZPC_FMC 91
+#define STM32_ETZPC_QSPI 92
+#define STM32_ETZPC_DLYBQ 93
+#define STM32_ETZPC_ETH1 94
+
+#endif /* _STM32_ETZPC_H_ */
--
2.15.0

2020-04-28 11:26:23

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 1/5] dt-bindings: bus: Add firewall bindings

Hi Benjamin,

On Mon, Apr 20, 2020 at 3:48 PM Benjamin Gaignard
<[email protected]> wrote:
>
> Add schemas for firewall consumer and provider.
>
> Signed-off-by: Benjamin Gaignard <[email protected]>

> +$id: http://devicetree.org/schemas/bus/stm32/firewall-consumer.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Common Bus Firewall consumer binding
> +
> +maintainers:
> + - Benjamin Gaignard <[email protected]>

This really needs a description: to tell what is going on and what
these firewalls
are for and how they are supposed to work.

I suppose just a bit of cut'n'paste from the cover letter :D

Otherwise it looks good to me.

Yours,
Linus Walleij

2020-04-28 13:18:13

by Benjamin GAIGNARD

[permalink] [raw]
Subject: Re: [PATCH 1/5] dt-bindings: bus: Add firewall bindings



On 4/28/20 1:24 PM, Linus Walleij wrote:
> Hi Benjamin,
>
> On Mon, Apr 20, 2020 at 3:48 PM Benjamin Gaignard
> <[email protected]> wrote:
>> Add schemas for firewall consumer and provider.
>>
>> Signed-off-by: Benjamin Gaignard <[email protected]>
>> +$id: http://devicetree.org/schemas/bus/stm32/firewall-consumer.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Common Bus Firewall consumer binding
>> +
>> +maintainers:
>> + - Benjamin Gaignard <[email protected]>
> This really needs a description: to tell what is going on and what
> these firewalls
> are for and how they are supposed to work.
Hi Linus,

Does the following description sound good for you:
Firewall properties provide the possible firewall bus controller
configurations for a device.
Bus firewall controllers are typically used to control if a hardware
block can perform read or write operations on bus.
The contents of the firewall bus configuration properties are defined by
the binding for the individual firewall controller device.
The first configuration 'firewall-0' or the one named 'default' is
applied before probing the device itself.

Regards,
Benjamin
>
> I suppose just a bit of cut'n'paste from the cover letter :D
>
> Otherwise it looks good to me.
>
> Yours,
> Linus Walleij

2020-04-28 14:34:57

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH 1/5] dt-bindings: bus: Add firewall bindings

On Tue, Apr 28, 2020 at 3:13 PM Benjamin GAIGNARD
<[email protected]> wrote:

> Does the following description sound good for you:
> Firewall properties provide the possible firewall bus controller
> configurations for a device.
> Bus firewall controllers are typically used to control if a hardware
> block can perform read or write operations on bus.
> The contents of the firewall bus configuration properties are defined by
> the binding for the individual firewall controller device.
> The first configuration 'firewall-0' or the one named 'default' is
> applied before probing the device itself.

Looks good to me!
Reviewed-by: Linus Walleij <[email protected]>
with this added.

Yours,
Linus Walleij