From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.3 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C77EBC4708C for ; Fri, 28 May 2021 09:59:18 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48E1E60724 for ; Fri, 28 May 2021 09:59:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 48E1E60724 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=foss.st.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 801A982E88; Fri, 28 May 2021 11:59:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=foss.st.com header.i=@foss.st.com header.b="j+dFOJbG"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 113B082EA1; Fri, 28 May 2021 11:59:15 +0200 (CEST) Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 1329782E7B for ; Fri, 28 May 2021 11:59:12 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=patrick.delaunay@foss.st.com Received: from pps.filterd (m0241204.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 14S9vc8T017367; Fri, 28 May 2021 11:59:10 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=subject : to : cc : references : from : message-id : date : mime-version : in-reply-to : content-type : content-transfer-encoding; s=selector1; bh=tahtoa8AosStau4w7KgbpPtgt78KXG8n2wHgf7BYpZQ=; b=j+dFOJbGkAZKp9Dp4IvKGsCM1XldHbdEa3ZPcg/IhbPQdWxKpN2srcmY6bKfQZl0YfK6 namXJUp5tG9NLU1076UwXDKZnaXOD1t2Y4djRwN3dR6UH3arRGj05gVA/6hXA7ltfZcX 7Lub+5uAaW9/A3Shp2dei+pZrEnI1RfnaKKxohZJK5D66mVByYr2NeKk+L9y39lUtVoP GwcmUzmtgtxbgGTANmq0K+9i6RvLtafTwehk+hIjLsqkbOsCmV7pX2twDrVEMY15gJHt 1M9LZtarEB3r4W/WwXt7MArq9RedyszmJHiFxlomWxq2o7TEof77IMObn06X1WQl7mel Fg== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 38tj2rkn5g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 28 May 2021 11:59:10 +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 A714E10002A; Fri, 28 May 2021 11:59:09 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag2node3.st.com [10.75.127.6]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 0B8F321ED51; Fri, 28 May 2021 11:59:09 +0200 (CEST) Received: from lmecxl0994.lme.st.com (10.75.127.51) by SFHDAG2NODE3.st.com (10.75.127.6) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 28 May 2021 11:59:08 +0200 Subject: Re: [PATCH v3 3/5] arm: stm32mp: Implement support for TZC 400 controller To: Alexandru Gagniuc , , CC: , References: <20210415164829.2302939-1-mr.nuke.me@gmail.com> <20210415164829.2302939-4-mr.nuke.me@gmail.com> From: Patrick DELAUNAY Message-ID: Date: Fri, 28 May 2021 11:59:08 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <20210415164829.2302939-4-mr.nuke.me@gmail.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-Originating-IP: [10.75.127.51] X-ClientProxiedBy: SFHDAG3NODE2.st.com (10.75.127.8) To SFHDAG2NODE3.st.com (10.75.127.6) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-05-28_04:2021-05-27, 2021-05-28 signatures=0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean Hi, On 4/15/21 6:48 PM, Alexandru Gagniuc wrote: > The purpose of this change is to allow configuring TrustZone (TZC) > memory permissions. For example, OP-TEE expects TZC regions to be > configured in a very particular way. The API presented here is > intended to allow exactly that. > > UCLASS support is not implemented, because it would not be too useful. > Changing TZC permissions needs to be done with care, so as not to cut > off access to memory we are currently using. One place where we can > use this is at the end of SPL, right before jumping to OP-TEE. > > Signed-off-by: Alexandru Gagniuc > --- > arch/arm/mach-stm32mp/Makefile | 1 + > arch/arm/mach-stm32mp/include/mach/tzc.h | 33 ++++++ > arch/arm/mach-stm32mp/tzc400.c | 136 +++++++++++++++++++++++ > 3 files changed, 170 insertions(+) > create mode 100644 arch/arm/mach-stm32mp/include/mach/tzc.h > create mode 100644 arch/arm/mach-stm32mp/tzc400.c > > diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile > index aa39867080..879c1961fe 100644 > --- a/arch/arm/mach-stm32mp/Makefile > +++ b/arch/arm/mach-stm32mp/Makefile > @@ -10,6 +10,7 @@ obj-y += bsec.o > > ifdef CONFIG_SPL_BUILD > obj-y += spl.o > +obj-y += tzc400.o > else > obj-y += cmd_stm32prog/ > obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o > diff --git a/arch/arm/mach-stm32mp/include/mach/tzc.h b/arch/arm/mach-stm32mp/include/mach/tzc.h > new file mode 100644 > index 0000000000..16db55c464 > --- /dev/null > +++ b/arch/arm/mach-stm32mp/include/mach/tzc.h > @@ -0,0 +1,33 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Simple API for configuring TrustZone memory regions > + * > + * The premise is that the desired TZC layout is known beforehand, and it can > + * be configured in one step. tzc_configure() provides this functionality. > + */ > +#ifndef MACH_TZC_H > +#define MACH_TZC_H > + > +#include > + > +enum tzc_sec_mode { > + TZC_ATTR_SEC_NONE = 0, > + TZC_ATTR_SEC_R = 1, > + TZC_ATTR_SEC_W = 2, > + TZC_ATTR_SEC_RW = 3 > +}; > + > +struct tzc_region { > + uintptr_t base; > + uintptr_t top; > + enum tzc_sec_mode sec_mode; > + uint16_t nsec_id; > + uint16_t filters_mask; > +}; > + > +int tzc_configure(uintptr_t tzc, const struct tzc_region *cfg); > +int tzc_disable_filters(uintptr_t tzc, uint16_t filters_mask); > +int tzc_enable_filters(uintptr_t tzc, uint16_t filters_mask); > +void tzc_dump_config(uintptr_t tzc); > + > +#endif /* MACH_TZC_H */ > diff --git a/arch/arm/mach-stm32mp/tzc400.c b/arch/arm/mach-stm32mp/tzc400.c > new file mode 100644 > index 0000000000..cdc4a40eda > --- /dev/null > +++ b/arch/arm/mach-stm32mp/tzc400.c > @@ -0,0 +1,136 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Simple API for configuring TrustZone memory restrictions for TZC400 > + */ > + > +#define LOG_CATEGORY LOGC_ARCH > + > +#include > +#include > + > +#define TZC_TIMEOUT_US 100 > + > +#define TZC_BUILD_CONFIG 0x00 > +#define TZC_ACTION 0x04 > +#define TZC_ACTION_NONE 0 > +#define TZC_ACTION_ERR 1 > +#define TZC_ACTION_INT 2 > +#define TZC_ACTION_INT_ERR 3 > +#define TZC_GATE_KEEPER 0x08 > + > +#define TZC_REGION0_OFFSET 0x100 > +#define TZC_REGION_CFG_SIZE 0x20 > +#define TZC_REGION1_OFFSET 0x120 > +#define TZC_REGION_BASE 0x00 > +#define TZC_REGION_TOP 0x08 > +#define TZC_REGION_ATTRIBUTE 0x10 > +#define TZC_REGION_ACCESS 0x14 > + > +static uint32_t tzc_read(uintptr_t tzc, size_t reg) > +{ > + return readl(tzc + reg); > +} > + > +static void tzc_write(uintptr_t tzc, size_t reg, uint32_t val) > +{ > + writel(val, tzc + reg); > +} > + > +static uint16_t tzc_config_get_active_filters(const struct tzc_region *cfg) > +{ > + uint16_t active_filters = 0; > + > + for ( ; cfg->top != 0; cfg++) > + active_filters |= cfg->filters_mask; > + > + return active_filters; > +} > + > +int tzc_configure(uintptr_t tzc, const struct tzc_region *cfg) > +{ > + uintptr_t region = tzc + TZC_REGION1_OFFSET; > + uint32_t nsid, attr_reg, active_filters; > + int ret; > + > + active_filters = tzc_config_get_active_filters(cfg); > + if (active_filters == 0) > + return -EINVAL; > + > + ret = tzc_disable_filters(tzc, active_filters); > + if (ret < 0) > + return ret; > + > + for ( ; cfg->top != 0; cfg++, region += TZC_REGION_CFG_SIZE) { > + attr_reg = (cfg->sec_mode & 0x03) << 30; > + attr_reg |= (cfg->filters_mask & 0x03) << 0; > + nsid = cfg->nsec_id & 0xffff; > + nsid |= nsid << 16; > + > + tzc_write(region, TZC_REGION_BASE, cfg->base); > + tzc_write(region, TZC_REGION_TOP, cfg->top); > + tzc_write(region, TZC_REGION_ACCESS, nsid); > + tzc_write(region, TZC_REGION_ATTRIBUTE, attr_reg); > + } > + > + tzc_write(tzc, TZC_ACTION, TZC_ACTION_ERR); > + return tzc_enable_filters(tzc, active_filters); > +} > + > +int tzc_disable_filters(uintptr_t tzc, uint16_t filters_mask) > +{ > + uint32_t gate = tzc_read(tzc, TZC_GATE_KEEPER); > + uint32_t filter_status = filters_mask << 16; > + > + gate &= ~filters_mask; > + tzc_write(tzc, TZC_GATE_KEEPER, gate); > + > + return readl_poll_timeout(tzc + TZC_GATE_KEEPER, gate, > + (gate & filter_status) == 0, TZC_TIMEOUT_US); > +} > + > +int tzc_enable_filters(uintptr_t tzc, uint16_t filters_mask) > +{ > + uint32_t gate = tzc_read(tzc, TZC_GATE_KEEPER); > + uint32_t filter_status = filters_mask << 16; > + > + gate |= filters_mask; > + tzc_write(tzc, TZC_GATE_KEEPER, gate); > + > + return readl_poll_timeout(tzc + TZC_GATE_KEEPER, gate, > + (gate & filter_status) == filter_status, > + TZC_TIMEOUT_US); > +} > + > +static const char *sec_access_str_from_attr(uint32_t attr) > +{ > + const char *const sec_mode[] = { "none", "RO ", "WO ", "RW " }; > + > + return sec_mode[(attr >> 30) & 0x03]; > +} > + > +void tzc_dump_config(uintptr_t tzc) > +{ > + uint32_t build_config, base, top, attr, nsaid; > + int num_regions, i; > + uintptr_t region; > + > + build_config = tzc_read(tzc, TZC_BUILD_CONFIG); > + num_regions = ((build_config >> 0) & 0x1f) + 1; > + > + for (i = 0; i < num_regions; i++) { > + region = tzc + TZC_REGION0_OFFSET + i * TZC_REGION_CFG_SIZE; > + > + base = tzc_read(region, TZC_REGION_BASE); > + top = tzc_read(region, TZC_REGION_TOP); > + attr = tzc_read(region, TZC_REGION_ATTRIBUTE); > + nsaid = tzc_read(region, TZC_REGION_ACCESS); > + > + if (attr == 0 && nsaid == 0) > + continue; > + > + log_info("TZC region %u: %08x->%08x - filters 0x%x\n", > + i, base, top, (attr >> 0) & 0xf); > + log_info("\t Secure access %s NSAID %08x\n", > + sec_access_str_from_attr(attr), nsaid); > + } > +} Any reason to preferĀ  uint16_t and uint32_t ? See checkpatch warning arch/arm/mach-stm32mp/include/mach/tzc.h:24: check: Prefer kernel type 'u16' over 'uint16_t' arch/arm/mach-stm32mp/include/mach/tzc.h:25: check: Prefer kernel type 'u16' over 'uint16_t' arch/arm/mach-stm32mp/tzc400.c:41: check: Prefer kernel type 'u16' over 'uint16_t' arch/arm/mach-stm32mp/tzc400.c:52: check: Prefer kernel type 'u32' over 'uint32_t' arch/arm/mach-stm32mp/tzc400.c:81: check: Prefer kernel type 'u32' over 'uint32_t' arch/arm/mach-stm32mp/tzc400.c:82: check: Prefer kernel type 'u32' over 'uint32_t' arch/arm/mach-stm32mp/tzc400.c:93: check: Prefer kernel type 'u32' over 'uint32_t' arch/arm/mach-stm32mp/tzc400.c:94: check: Prefer kernel type 'u32' over 'uint32_t' arch/arm/mach-stm32mp/tzc400.c:113: check: Prefer kernel type 'u32' over 'uint32_t' But except these remarks: Reviewed-by: Patrick Delaunay Thanks Patrick