Received: by 2002:a25:23cc:0:0:0:0:0 with SMTP id j195csp411895ybj; Tue, 5 May 2020 00:37:58 -0700 (PDT) X-Google-Smtp-Source: APiQypKLMJwtJGatOxD89YTSrCKaHOZZhX6Qrf0Z1Jt1yO3vNSMyMVgQsaOzJprVEHqk9L400MR5 X-Received: by 2002:a50:bb25:: with SMTP id y34mr1345321ede.237.1588664278382; Tue, 05 May 2020 00:37:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588664278; cv=none; d=google.com; s=arc-20160816; b=rPo+zEkbbclADIcRcmXrfxaf25AmnZewuw8OC62Gv/3XTNecBsy8A4i7pKqjEgjyEd RhpxjM1A1CG0b5WtjbsfqLwKoMb65yBnt1g6z0qPHh77r5b1Y4f9AKvDlJlO1YlAY61G 0sfQw8LajHSDdqHIxF08PIaFPH7Au4UPHvMEq/j9dJBI32HzmUV4/yBxb8ezDZzzvfeZ zgSeKwQNupbNVjcIFUmniXaQkOGN89z1jMhq+JH9tJS/X8Ur+VCkIRxKeza9oXa0AuGa Mj0qmWfzojbjrOwkBPC2oCSD8UBm3DVci46AV3643E5sI6SyTE1tTo8zU1xoFiHgb4vq lu5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=Hcw1lJCHjCweC5Z6YyOzJ+eYTpoFQ8lrStCDfhV3rK8=; b=IQTLX75CTimmgn/Q2kANChKbKF/RfXUB2cA6Il9TxVd93JmZzfoJeBlNYrDoVqaTnN SUUFZpSHdJWUczzPuHvH2Rh9iOWXEcEKZkrlOvcx574jkR1Z3aBTE4EjceCGTQMHH6nI 5GZdMM6AuBD2MZli4f5BAAmXbK3dx+QPa4XX1WayKq0ryBDOcTq5sh0oscQ14w3x7SbV oCCIyX9DNDtYDPiVjTOGiuaV98tN1nRFW0ilrXoxS9Mdd/flMKn90jdgIY9wAqJsLQWZ obRCacY91Kda54zBXIXUskpa0l5tLSJecUgFAxXjGMdIARxL/vFsAllLczTXWBRVPMf9 OzlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=NvCUBwbJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=st.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bs10si770917edb.429.2020.05.05.00.37.35; Tue, 05 May 2020 00:37:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=NvCUBwbJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=st.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728402AbgEEHdq (ORCPT + 99 others); Tue, 5 May 2020 03:33:46 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:53489 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725320AbgEEHdn (ORCPT ); Tue, 5 May 2020 03:33:43 -0400 Received: from pps.filterd (m0046037.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0457XEId019007; Tue, 5 May 2020 09:33:30 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=Hcw1lJCHjCweC5Z6YyOzJ+eYTpoFQ8lrStCDfhV3rK8=; b=NvCUBwbJPLV+N/Yh8VklY6hVXus75uFAsi+ligeMeWoh3oTK/LMAsutu/C61VKVVcXnR jQEQfhR/NO8swtsKIEmRkZkAxrkpfp66/ypt9GtEeCUzO8/fBYOJd5T/oPugzdKgBMvV owr/i9km/4kAHk0pwqIM6Zquws+NatF87vhH0jroMXfeXZsvCE2bBoetad+3TJleDO5p 8cnlkmwC0HScX3qIsR02hp09PfhPpwjkO9MncZX8PKpZa39lQ5YO2RUxHFO/s2cfCAKB EbmISt1uiDlQpVAZzZUC4zXZchZW8a7viuGMM45IBrL71G7FdEQW0miQr557Jj2u7oCs gQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30rxmveesk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 05 May 2020 09:33:30 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id AC4E3100038; Tue, 5 May 2020 09:33:29 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag3node3.st.com [10.75.127.9]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 9FCCF2A4927; Tue, 5 May 2020 09:33:29 +0200 (CEST) Received: from localhost (10.75.127.48) by SFHDAG3NODE3.st.com (10.75.127.9) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Tue, 5 May 2020 09:33:28 +0200 From: Benjamin Gaignard To: , , , , , CC: , , , , Benjamin Gaignard Subject: [PATCH v3 4/5] bus: stm32: Add stm32 ETZPC firewall bus controller Date: Tue, 5 May 2020 09:33:07 +0200 Message-ID: <20200505073308.22914-5-benjamin.gaignard@st.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20200505073308.22914-1-benjamin.gaignard@st.com> References: <20200505073308.22914-1-benjamin.gaignard@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.75.127.48] X-ClientProxiedBy: SFHDAG8NODE1.st.com (10.75.127.22) To SFHDAG3NODE3.st.com (10.75.127.9) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.676 definitions=2020-05-05_04:2020-05-04,2020-05-05 signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 for STMicroelectronics. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 "); +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 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