lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 14 Jan 2019 15:42:00 +0100 From: Benjamin Gaignard <benjamin.gaignard@...com> To: <broonie@...nel.org>, <robh@...nel.org>, <arnd@...db.de> CC: <linux-kernel@...r.kernel.org>, <loic.pallardy@...com>, <benjamin.gaignard@...aro.org>, Benjamin Gaignard <benjamin.gaignard@...com> Subject: [RFC 5/7] bus: domainsctrl: Add driver for STM32 ETZPC controller STM32 Extended TrustZone Protection Controller (ETZPC) got 3 domains: - secure: hardware blocks are only accessible by software running on trust zone. - non-secure: hardware blocks are accessible by non-secure software (i.e. linux kernel). - coprocessor: hardware blocks are only accessible by the corpocessor. Each hardware block status is defined by a 2 bits field and all of them are packed into 32 bits registers. ETZPC can manage up to 94 hardware blocks. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@...com> --- drivers/bus/domains/Kconfig | 7 ++ drivers/bus/domains/Makefile | 1 + drivers/bus/domains/stm32-etzpc.c | 140 ++++++++++++++++++++++++++ include/dt-bindings/bus/domains/stm32-etzpc.h | 25 +++++ 4 files changed, 173 insertions(+) create mode 100644 drivers/bus/domains/stm32-etzpc.c create mode 100644 include/dt-bindings/bus/domains/stm32-etzpc.h diff --git a/drivers/bus/domains/Kconfig b/drivers/bus/domains/Kconfig index 5ba15f750bee..7afd209e8c4f 100644 --- a/drivers/bus/domains/Kconfig +++ b/drivers/bus/domains/Kconfig @@ -4,4 +4,11 @@ config DOMAINS_CONTROLLERS bool "Support of bus domains controllers" depends on OF +config STM32_ETZPC + bool "STM32 ETZPC Domain Controller" + depends on DOMAINS_CONTROLLERS && MACH_STM32MP157 + help + Select y to enable STM32 Extended TrustZone Protection + Controller (ETZPC) + endmenu diff --git a/drivers/bus/domains/Makefile b/drivers/bus/domains/Makefile index 262338b7cad5..8000de6023a5 100644 --- a/drivers/bus/domains/Makefile +++ b/drivers/bus/domains/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_DOMAINS_CONTROLLERS) += domainsctrl.o +obj-$(CONFIG_STM32_ETZPC) += stm32-etzpc.o diff --git a/drivers/bus/domains/stm32-etzpc.c b/drivers/bus/domains/stm32-etzpc.c new file mode 100644 index 000000000000..8a03128a8715 --- /dev/null +++ b/drivers/bus/domains/stm32-etzpc.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2018 - All Rights Reserved + * Author: Benjamin Gaignard <benjamin.gaignard@...com> for STMicroelectronics. + */ + +#include <linux/device.h> +#include <linux/domainsctrl.h> +#include <linux/err.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <dt-bindings/bus/domains/stm32-etzpc.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(struct device *dev, + struct of_phandle_args *out_args) +{ + struct stm32_etzpc *etzpc = dev_get_drvdata(dev); + 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) { + dev_info(dev, "failed to set configuration: index %d, value %d\n", + index, value); + return -EINVAL; + } + + return 0; +} + +static struct domains_ctrl_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, + .fast_io = true, +}; + +static int stm32_etzpc_probe(struct platform_device *pdev) +{ + struct stm32_etzpc *etzpc; + struct resource *res; + void __iomem *mmio; + struct regmap *regmap; + int i; + + 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); + + return domainsctrl_register(&pdev->dev, &stm32_etzpc_ops); +} + +static int stm32_etzpc_remove(struct platform_device *pdev) +{ + domainsctrl_unregister(&pdev->dev); + + return 0; +} + +static const struct of_device_id stm32_etzpc_of_match[] = { + { .compatible = "st,stm32-etzpc" }, + { /* end node */ } +}; +MODULE_DEVICE_TABLE(of, stm32_etzpc_of_match); + +static struct platform_driver stm32_etzpc_driver = { + .probe = stm32_etzpc_probe, + .remove = stm32_etzpc_remove, + .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 <benjamin.gaignard@...com>"); +MODULE_DESCRIPTION("STMicroelectronics STM32 Bus Dommains Controller"); diff --git a/include/dt-bindings/bus/domains/stm32-etzpc.h b/include/dt-bindings/bus/domains/stm32-etzpc.h new file mode 100644 index 000000000000..93190fa29a9c --- /dev/null +++ b/include/dt-bindings/bus/domains/stm32-etzpc.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) STMicroelectronics 2018 - All Rights Reserved + * Author: Benjamin Gaignard <benjamin.gaignard@...com> for STMicroelectronics. + */ + +#ifndef _STM32_ETZPC_H_ +#define _STM32_ETZPC_H_ + +/* ETZPC domains: secure, non-secure or coprocessor*/ +#define STM32_ETZPC_SECURE 1 +#define STM32_ETPCZ_COPRO 2 +#define STM32_ETZPC_NON_SECURE 3 + +/* ETZPC hard blaokcs 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_CEC 38 + +#endif /* _STM32_ETZPC_H_ */ -- 2.15.0
Powered by blists - more mailing lists