Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp1951378ybg; Fri, 5 Jun 2020 01:36:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx6TN95slMOxWxyGdEGj/pJmH3+NTogZ6XloESuvAz3vyBCbSADmwXS1jXWgzjHbmPiKq8Z X-Received: by 2002:a50:9ee4:: with SMTP id a91mr8585486edf.172.1591346193770; Fri, 05 Jun 2020 01:36:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591346193; cv=none; d=google.com; s=arc-20160816; b=YxHAKo2l+5i4YY8US4DubSksWfrVNRP6T1kQfyCisq2IiiW9i1q+53woVRCaP7rZv3 gbOyb11vsiJtS9X0Kqwv/CdLuVOPmNmgg4oQ5ZQQVLI1Jv1/I1D9H2kdN2W3Vyw/8dlK WfKRHaWmKzIvjMmtU/YqWcypchNDXPZQI4B/v8UUfQhOrAyIf1Fa4blU/S4yDgWMFbiP 54LbKFEj50KeLj7EvXQ4NMjJBIzrrbjrlRY6Kf8txTGbIkkRyFBTaLN5qr/8dig1x3xa b8ilKuCt9MXQanBHzC8qlDMhq+4Nv2nlYpmEvX0eyF0Fbya74FWzYdXWvH2Z71kTrNIZ MSlw== 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=Noyc1sz1H7BSum1HD5Fbfe/NwPdfyZxzQktyj1gbcR4=; b=tkaLqs56FZmlrbCHI8Q/c0ZoZwP8PbejnXjImRila5l36wyAEDm6LgE3L9a+wxd7qu zl9H43HTZfzF3GYHjknKyRlXLpZGzlaBvSB5wod+SS37BICdoVb0jkXOacy9eY9SJguV FGxPDon2hBFTJo+y5YtXH2oMeb83qorAdkU3B4iTh0XT/b+poeM3lj3Cww13W05cuMrE trH99pIayVhJLdLP+Q5YdbsXkB6Yz1ZwOhihJKO7dDGkh3Pv0Dr2l8JQy/RYY+BxWG/4 hE58d4YTzfluIncHOdeKgXwus/vPM7epvDz5rS4eNcxH2clBelwMMkMBjN4nyfrSgnqq fQOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@st.com header.s=STMicroelectronics header.b=rtXi0L3t; 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 ds15si3617652ejc.14.2020.06.05.01.36.10; Fri, 05 Jun 2020 01:36:33 -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=rtXi0L3t; 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 S1726210AbgFEIeU (ORCPT + 99 others); Fri, 5 Jun 2020 04:34:20 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:40498 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726109AbgFEIeS (ORCPT ); Fri, 5 Jun 2020 04:34:18 -0400 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0558WAv7010468; Fri, 5 Jun 2020 10:33:56 +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=Noyc1sz1H7BSum1HD5Fbfe/NwPdfyZxzQktyj1gbcR4=; b=rtXi0L3t/MClH5Dxfjg+P0+0WQTeimCI7uY3sEGrqWRgkplqKrjTW1+azHLMAzKNonuT fkeoJLEoZuRKV53vmQj46g/AF4c09VhoU6rJKNnJ8J+hSsUOeMouVYJ9UtnS/PzIbqCs fEfkp5NYxstLoJIrg6RI0//aRyqyiZDyjToCJVbD7oRoTad3r74mPaRDRZ/jRfor8X1P Rk+Ur1j1ue8aG43EdgcqzzaBUivgm9ZSN1L6pi4Crkd10ikxNtHethTushitQwy+w9LW LaZBuygiOdvmk1oTkO80dX6JnlnlQCBofjKy8lSBQOgKSnm1sDtA6aPk0+BncsbyUD36 pg== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 31faset4ny-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 05 Jun 2020 10:33:56 +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 042DE100038; Fri, 5 Jun 2020 10:33:56 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag3node3.st.com [10.75.127.9]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id ECEAA2B21C1; Fri, 5 Jun 2020 10:33:55 +0200 (CEST) Received: from localhost (10.75.127.44) by SFHDAG3NODE3.st.com (10.75.127.9) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Fri, 5 Jun 2020 10:33:55 +0200 From: Benjamin Gaignard To: , , , , CC: , , , , , Benjamin Gaignard Subject: [PATCH v4 4/5] bus: stm32: Add stm32 ETZPC firewall bus controller Date: Fri, 5 Jun 2020 10:33:47 +0200 Message-ID: <20200605083348.13880-5-benjamin.gaignard@st.com> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20200605083348.13880-1-benjamin.gaignard@st.com> References: <20200605083348.13880-1-benjamin.gaignard@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.75.127.44] X-ClientProxiedBy: SFHDAG4NODE2.st.com (10.75.127.11) To SFHDAG3NODE3.st.com (10.75.127.9) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.687 definitions=2020-06-05_01:2020-06-04,2020-06-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 | 163 ++++++++++++++++++++++++++++ include/dt-bindings/bus/stm32/stm32-etzpc.h | 90 +++++++++++++++ 4 files changed, 262 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..ad0e16eea66b --- /dev/null +++ b/drivers/bus/stm32/stm32-etzpc.c @@ -0,0 +1,163 @@ +// 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(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) { + 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 device *firewall; + struct regmap *regmap; + struct resource *res; + void __iomem *mmio; + 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); + + firewall = firewall_register(dev_of_node(&pdev->dev), + &stm32_etzpc_ops); + if (!firewall) + return -EINVAL; + + dev_set_drvdata(firewall, etzpc); + + 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