From 0c9f91cf699565c858e650d19bbdcab513d5001a Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 20 Jul 2021 19:20:07 +0100 Subject: refactor(gicv3): rename GIC Clayton to GIC-700 The GIC IP formerly known as "GIC Clayton" has been released under the name of "GIC-700". Rename occurences of Clayton in comments and macro names to reflect the official name. Change-Id: Ie8c55f7da7753127d58c8382b0033c1b486f7909 Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gic-x00.c | 8 ++++---- drivers/arm/gic/v3/gic600_multichip_private.h | 4 ++-- plat/arm/board/rdn2/platform.mk | 2 +- plat/arm/board/rdv1/platform.mk | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index 6e106babf..eccfd976f 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -24,7 +24,7 @@ #define GICR_PWRR 0x24U #define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) #define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) -#define IIDR_MODEL_ARM_GIC_CLAYTON U(0x0400043b) +#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) /* GICR_PWRR fields */ #define PWRR_RDPD_SHIFT 0 @@ -46,7 +46,7 @@ #if GICV3_SUPPORT_GIC600 -/* GIC-600/Clayton specific accessor functions */ +/* GIC-600/700 specific accessor functions */ static void gicr_write_pwrr(uintptr_t base, unsigned int val) { mmio_write_32(base + GICR_PWRR, val); @@ -123,12 +123,12 @@ static bool gicv3_redists_need_power_mgmt(uintptr_t gicr_base) uint32_t reg = mmio_read_32(gicr_base + GICR_IIDR); /* - * The Arm GIC-600 and GIC-Clayton models have their redistributors + * The Arm GIC-600 and GIC-700 models have their redistributors * powered down at reset. */ return (((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) || ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600AE) || - ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_CLAYTON)); + ((reg & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)); } #endif /* GICV3_SUPPORT_GIC600 */ diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index fe4134cba..27b8e817f 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -28,8 +28,8 @@ #define GICD_DCHIPR_RT_OWNER_SHIFT 4 /* - * If GIC v4 extension is enabled, then use SPI macros specific to GIC-Clayton. - * Other shifts and mask remains same between GIC-600 and GIC-Clayton. + * If GIC v4 extension is enabled, then use SPI macros specific to GIC-700. + * Other shifts and mask remains same between GIC-600 and GIC-700. */ #if GIC_ENABLE_V4_EXTN #define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9 diff --git a/plat/arm/board/rdn2/platform.mk b/plat/arm/board/rdn2/platform.mk index 794f8974f..5b24c32bd 100644 --- a/plat/arm/board/rdn2/platform.mk +++ b/plat/arm/board/rdn2/platform.mk @@ -3,7 +3,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# RD-N2 platform uses GIC-Clayton which is based on GICv4.1 +# RD-N2 platform uses GIC-700 which is based on GICv4.1 GIC_ENABLE_V4_EXTN := 1 include plat/arm/css/sgi/sgi-common.mk diff --git a/plat/arm/board/rdv1/platform.mk b/plat/arm/board/rdv1/platform.mk index 1ae85de7c..11f52127e 100644 --- a/plat/arm/board/rdv1/platform.mk +++ b/plat/arm/board/rdv1/platform.mk @@ -3,7 +3,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# RD-V1 platform uses GIC-Clayton which is based on GICv4.1 +# RD-V1 platform uses GIC-700 which is based on GICv4.1 GIC_ENABLE_V4_EXTN := 1 include plat/arm/css/sgi/sgi-common.mk -- cgit v1.2.3 From 12349d3332325f56462b780e36f31ebac7976d38 Mon Sep 17 00:00:00 2001 From: Maksims Svecovs Date: Thu, 6 May 2021 19:03:48 +0100 Subject: docs(ff-a): managed exit parameter separation As of DEN0077A FF-A v1.1 Beta0 section 5.2, managed exit support is moved out of messaging-method field and is described in a separate field. Signed-off-by: Maksims Svecovs Change-Id: Icb12d9dc0d10b11c105dc1920e5212b0359af147 --- docs/components/ffa-manifest-binding.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/components/ffa-manifest-binding.rst b/docs/components/ffa-manifest-binding.rst index 437df6748..df2985ccc 100644 --- a/docs/components/ffa-manifest-binding.rst +++ b/docs/components/ffa-manifest-binding.rst @@ -110,10 +110,13 @@ Partition Properties - Specifies which messaging methods are supported by the partition, set bit means the feature is supported, clear bit - not supported: - - Bit[0]: support for receiving direct message requests - - Bit[1]: support for sending direct messages - - Bit[2]: support for indirect messaging - - Bit[3]: support for managed exit + - Bit[0]: partition can receive direct requests if set + - Bit[1]: partition can send direct requests if set + - Bit[2]: partition can send and receive indirect messages + +- managed-exit + - value type: + - Specifies if managed exit is supported. - has-primary-scheduler - value type: -- cgit v1.2.3 From 068fe919613197bf221c00fb84a1d94c66a7a8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 26 Jun 2021 16:26:56 +0200 Subject: fix(plat/marvell/a3k): update information about PCIe abort hack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A3700 plat_ea_handler was introduced into TF-A codebase just because of bugs in U-Boot and Linux kernel PCIe controller driver pci-aardvark.c. These bugs were finally fixed in both U-Boot and Linux kernel drivers: https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01 https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7 Add all these information into comments, including printing error message into a3k plat_ea_handler. Also check that abort is really asynchronous and comes from lower level than EL3. Signed-off-by: Pali Rohár Change-Id: I46318d221b39773d5e25b3a0221d7738736ffdf1 --- plat/marvell/armada/a3k/common/a3700_ea.c | 65 ++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c index 3a4f7203b..dde92e38a 100644 --- a/plat/marvell/armada/a3k/common/a3700_ea.c +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -8,14 +8,75 @@ #include #include #include +#include -#define ADVK_SERROR_SYNDROME 0xbf000002 +#define A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS 0xbf000002 + +#if !ENABLE_BACKTRACE +static const char *get_el_str(unsigned int el) +{ + if (el == MODE_EL3) { + return "EL3"; + } else if (el == MODE_EL2) { + return "EL2"; + } + return "S-EL1"; +} +#endif /* !ENABLE_BACKTRACE */ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) { - if (syndrome == ADVK_SERROR_SYNDROME) + unsigned int level = (unsigned int)GET_EL(read_spsr_el3()); + + /* + * Asynchronous External Abort with syndrome 0xbf000002 on Cortex A53 + * core means SError interrupt caused by AXI SLVERR on external access. + * + * In most cases this indicates a bug in U-Boot or Linux kernel driver + * pci-aardvark.c which implements access to A3700 PCIe config space. + * Driver does not wait for PCIe PIO transfer completion and try to + * start a new PCIe PIO transfer while previous has not finished yet. + * A3700 PCIe controller in this case sends SLVERR via AXI which results + * in a fatal Asynchronous SError interrupt on Cortex A53 CPU. + * + * Following patches fix that bug in U-Boot and Linux kernel drivers: + * https://source.denx.de/u-boot/u-boot/-/commit/eccbd4ad8e4e182638eafbfb87ac139c04f24a01 + * https://git.kernel.org/stable/c/f18139966d072dab8e4398c95ce955a9742e04f7 + * + * As a hacky workaround for unpatched U-Boot and Linux kernel drivers + * ignore all asynchronous aborts with that syndrome value received on + * CPU from level lower than EL3. + * + * Because these aborts are delivered on CPU asynchronously, they are + * imprecise and we cannot check the real reason of abort and neither + * who and why sent this abort. We expect that on A3700 it is always + * PCIe controller. + * + * Hence ignoring all aborts with this syndrome value is just a giant + * hack that we need only because of bugs in old U-Boot and Linux kernel + * versions and because it was decided that TF-A would implement this + * hack for U-Boot and Linux kernel it in this way. New patched U-Boot + * and kernel versions do not need it anymore. + * + * Links to discussion about this workaround: + * https://lore.kernel.org/linux-pci/20190316161243.29517-1-repk@triplefau.lt/ + * https://lore.kernel.org/linux-pci/971be151d24312cc533989a64bd454b4@www.loen.fr/ + * https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541 + */ + if (level < MODE_EL3 && ea_reason == ERROR_EA_ASYNC && + syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) { + ERROR_NL(); + ERROR("Ignoring Asynchronous External Abort with" + " syndrome 0x%llx received on 0x%lx from %s\n", + syndrome, read_mpidr_el1(), get_el_str(level)); + ERROR("SError interrupt: AXI SLVERR on external access\n"); + ERROR("This indicates a bug in pci-aardvark.c driver\n"); + ERROR("Please update U-Boot/Linux to the latest version\n"); + ERROR_NL(); + console_flush(); return; + } plat_default_ea_handler(ea_reason, syndrome, cookie, handle, flags); } -- cgit v1.2.3 From 3017e932768c7357a1a41493c58323419e9a1ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Jul 2021 15:10:27 +0200 Subject: fix(plat/marvell/a3k): disable HANDLE_EA_EL3_FIRST by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was enabled in commit 3c7dcdac5c50 ("marvell/a3700: Prevent SError accessing PCIe link while it is down") with a workaround for a bug found in U-Boot and Linux kernel driver pci-aardvark.c (PCIe controller driver for Armada 37xx SoC) which results in SError interrupt caused by AXI SLVERR on external access (syndrome 0xbf000002) and immediate kernel panic. Now when proper patches are in both U-Boot and Linux kernel projects, this workaround in TF-A should not have to be enabled by default anymore as it has unwanted side effects like propagating all external aborts, including non-fatal/correctable into EL3 and making them as fatal which cause immediate abort. Add documentation for HANDLE_EA_EL3_FIRST build option into Marvell Armada build section. Signed-off-by: Pali Rohár Change-Id: Ic92b65bf9923505ab682830afb66c2f6cec70491 --- docs/plat/marvell/armada/build.rst | 23 +++++++++++++++++++++++ plat/marvell/armada/a3k/common/a3700_common.mk | 6 ++++-- plat/marvell/armada/a3k/common/a3700_ea.c | 4 ++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index ca84be6bc..b10fb3a4c 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -139,6 +139,29 @@ A7K/8K/CN913x specific build options: Armada37x0 specific build options: +- HANDLE_EA_EL3_FIRST + + When ``HANDLE_EA_EL3_FIRST=1``, External Aborts and SError Interrupts will be always trapped + in TF-A. TF-A in this case enables dirty hack / workaround for a bug found in U-Boot and + Linux kernel PCIe controller driver pci-aardvark.c, traps and then masks SError interrupt + caused by AXI SLVERR on external access (syndrome 0xbf000002). + + Otherwise when ``HANDLE_EA_EL3_FIRST=0``, these exceptions will be trapped in the current + exception level (or in EL1 if the current exception level is EL0). So exceptions caused by + U-Boot will be trapped in U-Boot, exceptions caused by Linux kernel (or user applications) + will be trapped in Linux kernel. + + Mentioned bug in pci-aardvark.c driver is fixed in U-Boot version v2021.07 and Linux kernel + version v5.13 (workarounded since Linux kernel version 5.9) and also backported in Linux + kernel stable releases since versions v5.12.13, v5.10.46, v5.4.128, v4.19.198, v4.14.240. + + If target system has already patched version of U-Boot and Linux kernel then it is strongly + recommended to not enable this workaround as it disallows propagating of all External Aborts + to running Linux kernel and makes correctable errors as fatal aborts. + + This option is now disabled by default. In past this option was enabled by default in + TF-A versions v2.2, v2.3, v2.4 and v2.5. + - CM3_SYSTEM_RESET When ``CM3_SYSTEM_RESET=1``, the Cortex-M3 secure coprocessor will be used for system reset. diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 0a8974293..238587d6a 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -13,7 +13,6 @@ PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY) PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common -HANDLE_EA_EL3_FIRST := 1 include plat/marvell/marvell.mk @@ -53,7 +52,6 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/dram_win.c \ $(PLAT_COMMON_BASE)/io_addr_dec.c \ $(PLAT_COMMON_BASE)/marvell_plat_config.c \ - $(PLAT_COMMON_BASE)/a3700_ea.c \ $(PLAT_FAMILY_BASE)/$(PLAT)/plat_bl31_setup.c \ $(MARVELL_COMMON_BASE)/marvell_cci.c \ $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \ @@ -63,6 +61,10 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ $(PLAT_COMMON_BASE)/a3700_sip_svc.c \ $(MARVELL_DRV) +ifeq ($(HANDLE_EA_EL3_FIRST),1) +BL31_SOURCES += $(PLAT_COMMON_BASE)/a3700_ea.c +endif + ifeq ($(CM3_SYSTEM_RESET),1) BL31_SOURCES += $(PLAT_COMMON_BASE)/cm3_system_reset.c endif diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c index dde92e38a..4a58fc6a4 100644 --- a/plat/marvell/armada/a3k/common/a3700_ea.c +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -24,6 +24,10 @@ static const char *get_el_str(unsigned int el) } #endif /* !ENABLE_BACKTRACE */ +/* + * This source file with custom plat_ea_handler function is compiled only when + * building TF-A with compile option HANDLE_EA_EL3_FIRST=1 + */ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) { -- cgit v1.2.3 From 40ff90747098ed9d2a09894d1a886c10ca76cee6 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 23 Jun 2021 20:02:39 +0100 Subject: feat(trbe): initialize trap settings of trace buffer control registers access Trap bits of trace buffer control registers access are in architecturally UNKNOWN state at boot hence 1. Initialized these bits to zero to prohibit trace buffer control registers accesses in lower ELs (EL2, EL1) in all security states when FEAT_TRBE is implemented 2. Also, these bits are RES0 when FEAT_TRBE is not implemented, and hence setting it to zero also aligns with the Arm ARM reference recommendation, that mentions software must writes RES0 bits with all 0s Change-Id: If2752fd314881219f232f21d8e172a9c6d341ea1 Signed-off-by: Manish V Badarkhe --- include/arch/aarch64/arch.h | 5 +++++ include/arch/aarch64/el3_common_macros.S | 9 ++++++++- lib/el3_runtime/aarch64/context_mgmt.c | 8 +++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index c12dbc4b4..d71ec00c9 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -442,6 +442,9 @@ #define MDCR_EnPMSN_BIT (ULL(1) << 36) #define MDCR_MPMX_BIT (ULL(1) << 35) #define MDCR_MCCD_BIT (ULL(1) << 34) +#define MDCR_NSTB(x) ((x) << 24) +#define MDCR_NSTB_EL1 ULL(0x3) +#define MDCR_NSTBE (ULL(1) << 26) #define MDCR_MTPME_BIT (ULL(1) << 28) #define MDCR_TDCC_BIT (ULL(1) << 27) #define MDCR_SCCD_BIT (ULL(1) << 23) @@ -465,6 +468,8 @@ /* MDCR_EL2 definitions */ #define MDCR_EL2_MTPME (U(1) << 28) #define MDCR_EL2_HLP (U(1) << 26) +#define MDCR_EL2_E2TB(x) ((x) << 24) +#define MDCR_EL2_E2TB_EL1 U(0x3) #define MDCR_EL2_HCCD (U(1) << 23) #define MDCR_EL2_TTRF (U(1) << 19) #define MDCR_EL2_HPMD (U(1) << 17) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 973433575..2aa22226f 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -126,12 +126,19 @@ * Debug is not implemented this bit does not have any effect on the * counters unless there is support for the implementation defined * authentication interface ExternalSecureNoninvasiveDebugEnabled(). + * + * MDCR_EL3.NSTB, MDCR_EL3.NSTBE: Set to zero so that Trace Buffer + * owning security state is Secure state. If FEAT_TRBE is implemented, + * accesses to Trace Buffer control registers at EL2 and EL1 in any + * security state generates trap exceptions to EL3. + * If FEAT_TRBE is not implemented, these bits are RES0. * --------------------------------------------------------------------- */ mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \ MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \ MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \ - MDCR_TDA_BIT | MDCR_TPM_BIT)) + MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \ + MDCR_NSTBE)) msr mdcr_el3, x0 diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 7c6f953b2..1a765e739 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -565,6 +565,11 @@ void cm_prepare_el3_exit(uint32_t security_state) * * MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the * architecturally-defined reset value. + * + * MDCR_EL2.E2TB: Set to zero so that the trace Buffer + * owning exception level is NS-EL1 and, tracing is + * prohibited at NS-EL2. These bits are RES0 when + * FEAT_TRBE is not implemented. */ mdcr_el2 = ((MDCR_EL2_RESET_VAL | MDCR_EL2_HLP | MDCR_EL2_HPMD) | @@ -574,7 +579,8 @@ void cm_prepare_el3_exit(uint32_t security_state) MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT | MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT | MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT | - MDCR_EL2_TPMCR_BIT); + MDCR_EL2_TPMCR_BIT | + MDCR_EL2_E2TB(MDCR_EL2_E2TB_EL1)); write_mdcr_el2(mdcr_el2); -- cgit v1.2.3 From 813524ea9d2e4138246b8f77a772299e52fb33bc Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 2 Jul 2021 09:10:56 +0100 Subject: feat(trbe): enable access to trace buffer control registers from lower NS EL Introduced a build flag 'ENABLE_TRBE_FOR_NS' to enable trace buffer control registers access in NS-EL2, or NS-EL1 (when NS-EL2 is implemented but unused). Change-Id: I285a672ccd395eebd377714c992bb21062a729cc Signed-off-by: Manish V Badarkhe --- Makefile | 2 ++ bl31/bl31.mk | 4 +++ docs/getting_started/build-options.rst | 6 ++++ include/arch/aarch64/arch.h | 5 +++ include/lib/extensions/trbe.h | 12 +++++++ lib/el3_runtime/aarch64/context_mgmt.c | 6 ++++ lib/extensions/trbe/trbe.c | 63 ++++++++++++++++++++++++++++++++++ make_helpers/defaults.mk | 11 ++++++ 8 files changed, 109 insertions(+) create mode 100644 include/lib/extensions/trbe.h create mode 100644 lib/extensions/trbe/trbe.c diff --git a/Makefile b/Makefile index b4bebf17f..c8ffdab06 100644 --- a/Makefile +++ b/Makefile @@ -964,6 +964,7 @@ $(eval $(call assert_booleans,\ ENABLE_FEAT_RNG \ ENABLE_FEAT_SB \ PSA_FWU_SUPPORT \ + ENABLE_TRBE_FOR_NS \ ))) $(eval $(call assert_numerics,\ @@ -1064,6 +1065,7 @@ $(eval $(call add_defines,\ NR_OF_FW_BANKS \ NR_OF_IMAGES_IN_FW_BANK \ PSA_FWU_SUPPORT \ + ENABLE_TRBE_FOR_NS \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 1fdf545da..dc3d3c0be 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -90,6 +90,10 @@ ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1) BL31_SOURCES += lib/extensions/mpam/mpam.c endif +ifeq (${ENABLE_TRBE_FOR_NS},1) +BL31_SOURCES += lib/extensions/trbe/trbe.c +endif + ifeq (${WORKAROUND_CVE_2017_5715},1) BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \ lib/cpus/aarch64/wa_cve_2017_5715_mmu.S diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 901a72a9b..57b880a9f 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -775,6 +775,12 @@ Common build options functions that wait for an arbitrary time length (udelay and mdelay). The default value is 0. +- ``ENABLE_TRBE_FOR_NS``: This flag is used to enable access of trace buffer + control registers from NS ELs, NS-EL2 or NS-EL1(when NS-EL2 is implemented + but unused) when FEAT_TRBE is implemented. TRBE is an optional architectural + feature for AArch64. The default is 0 and it is automatically disabled when + the target architecture is AArch32. + GICv3 driver options -------------------- diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index d71ec00c9..47e02ce43 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -192,6 +192,11 @@ #define ID_AA64DFR0_PMS_SHIFT U(32) #define ID_AA64DFR0_PMS_MASK ULL(0xf) +/* ID_AA64DFR0_EL1.TraceBuffer definitions */ +#define ID_AA64DFR0_TRACEBUFFER_SHIFT U(44) +#define ID_AA64DFR0_TRACEBUFFER_MASK ULL(0xf) +#define ID_AA64DFR0_TRACEBUFFER_SUPPORTED ULL(1) + /* ID_AA64DFR0_EL1.MTPMU definitions (for ARMv8.6+) */ #define ID_AA64DFR0_MTPMU_SHIFT U(48) #define ID_AA64DFR0_MTPMU_MASK ULL(0xf) diff --git a/include/lib/extensions/trbe.h b/include/lib/extensions/trbe.h new file mode 100644 index 000000000..1753ab6bf --- /dev/null +++ b/include/lib/extensions/trbe.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TRBE_H +#define TRBE_H + +void trbe_enable(void); + +#endif /* TRBE_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 1a765e739..9eb66ed84 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -348,6 +349,11 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) #if ENABLE_MPAM_FOR_LOWER_ELS mpam_enable(el2_unused); #endif + +#if ENABLE_TRBE_FOR_NS + trbe_enable(); +#endif /* ENABLE_TRBE_FOR_NS */ + #endif } diff --git a/lib/extensions/trbe/trbe.c b/lib/extensions/trbe/trbe.c new file mode 100644 index 000000000..9f754d521 --- /dev/null +++ b/lib/extensions/trbe/trbe.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +static void tsb_csync(void) +{ + /* + * The assembler does not yet understand the tsb csync mnemonic + * so use the equivalent hint instruction. + */ + __asm__ volatile("hint #18"); +} + +static bool trbe_supported(void) +{ + uint64_t features; + + features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEBUFFER_SHIFT; + return ((features & ID_AA64DFR0_TRACEBUFFER_MASK) == + ID_AA64DFR0_TRACEBUFFER_SUPPORTED); +} + +void trbe_enable(void) +{ + uint64_t val; + + if (trbe_supported()) { + /* + * MDCR_EL3.NSTB = 0b11 + * Allow access of trace buffer control registers from NS-EL1 + * and NS-EL2, tracing is prohibited in Secure and Realm state + * (if implemented). + */ + val = read_mdcr_el3(); + val |= MDCR_NSTB(MDCR_NSTB_EL1); + write_mdcr_el3(val); + } +} + +static void *trbe_drain_trace_buffers_hook(const void *arg __unused) +{ + if (trbe_supported()) { + /* + * Before switching from normal world to secure world + * the trace buffers need to be drained out to memory. This is + * required to avoid an invalid memory access when TTBR is switched + * for entry to S-EL1. + */ + tsb_csync(); + dsbnsh(); + } + + return (void *)0; +} + +SUBSCRIBE_TO_EVENT(cm_entering_secure_world, trbe_drain_trace_buffers_hook); diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 72f84b52e..e95d2268f 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -355,3 +355,14 @@ NR_OF_IMAGES_IN_FW_BANK := 1 # Disable Firmware update support by default PSA_FWU_SUPPORT := 0 + +# By default, disable access of trace buffer control registers from NS +# lower ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused +# if FEAT_TRBE is implemented. +# Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in +# AArch32. +ifneq (${ARCH},aarch32) + ENABLE_TRBE_FOR_NS := 0 +else + override ENABLE_TRBE_FOR_NS := 0 +endif -- cgit v1.2.3 From 2031d6166a58623ae59034bc2353fcd2fabe9c30 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 7 Jul 2021 16:27:10 +0100 Subject: feat(sys_reg_trace): initialize trap settings of trace system registers access Trap bits of trace system registers access are in architecturally UNKNOWN state at boot hence 1. Initialized trap bits to one to prohibit trace system registers accesses in lower ELs (EL2, EL1) in all security states when system trace registers are implemented. 2. These bits are RES0 in the absence of system trace register support and hence set it to zero to aligns with the Arm ARM reference recommendation,that mentions software must writes RES0 bits with all 0s. Change-Id: I4b6c15cda882325273492895d72568b29de89ca3 Signed-off-by: Manish V Badarkhe --- include/arch/aarch32/arch.h | 7 +++++++ include/arch/aarch32/el3_common_macros.S | 12 ++++++++++++ include/arch/aarch64/arch.h | 6 ++++++ include/arch/aarch64/el3_common_macros.S | 11 +++++++++++ 4 files changed, 36 insertions(+) diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 54ec00953..5b160a227 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -102,6 +102,12 @@ /* CSSELR definitions */ #define LEVEL_SHIFT U(1) +/* ID_DFR0_EL1 definitions */ +#define ID_DFR0_COPTRC_SHIFT U(12) +#define ID_DFR0_COPTRC_MASK U(0xf) +#define ID_DFR0_COPTRC_SUPPORTED U(1) +#define ID_DFR0_COPTRC_LENGTH U(4) + /* ID_DFR1_EL1 definitions */ #define ID_DFR1_MTPMU_SHIFT U(0) #define ID_DFR1_MTPMU_MASK U(0xf) @@ -516,6 +522,7 @@ #define CTR p15, 0, c0, c0, 1 #define CNTFRQ p15, 0, c14, c0, 0 #define ID_MMFR4 p15, 0, c0, c2, 6 +#define ID_DFR0 p15, 0, c0, c1, 2 #define ID_DFR1 p15, 0, c0, c3, 5 #define ID_PFR0 p15, 0, c0, c1, 0 #define ID_PFR1 p15, 0, c0, c1, 1 diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 7fff4c754..49e8518d3 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -63,11 +63,23 @@ * cp11 field is ignored, but is set to same value as cp10. The cp10 * field is set to allow access to Advanced SIMD and floating point * features from both Security states. + * + * NSACR.NSTRCDIS: When system register trace implemented, Set to one + * so that NS System register accesses to all implemented trace + * registers are disabled. + * When system register trace is not implemented, this bit is RES0 and + * hence set to zero. * --------------------------------------------------------------------- */ ldcopr r0, NSACR and r0, r0, #NSACR_IMP_DEF_MASK orr r0, r0, #(NSACR_RESET_VAL | NSACR_ENABLE_FP_ACCESS) + ldcopr r1, ID_DFR0 + ubfx r1, r1, #ID_DFR0_COPTRC_SHIFT, #ID_DFR0_COPTRC_LENGTH + cmp r1, #ID_DFR0_COPTRC_SUPPORTED + bne 1f + orr r0, r0, #NSTRCDIS_BIT +1: stcopr r0, NSACR isb diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 47e02ce43..2a3812394 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -188,6 +188,12 @@ #define EL_IMPL_A64ONLY ULL(1) #define EL_IMPL_A64_A32 ULL(2) +/* ID_AA64DFR0_EL1.TraceVer definitions */ +#define ID_AA64DFR0_TRACEVER_SHIFT U(4) +#define ID_AA64DFR0_TRACEVER_MASK ULL(0xf) +#define ID_AA64DFR0_TRACEVER_SUPPORTED ULL(1) +#define ID_AA64DFR0_TRACEVER_LENGTH U(4) + /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */ #define ID_AA64DFR0_PMS_SHIFT U(32) #define ID_AA64DFR0_PMS_MASK ULL(0xf) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 2aa22226f..18fe0de1e 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -186,6 +186,12 @@ * CPTR_EL3.TCPAC: Set to zero so that any accesses to CPACR_EL1, * CPTR_EL2, CPACR, or HCPTR do not trap to EL3. * + * CPTR_EL3.TTA: Set to one so that accesses to the trace system + * registers trap to EL3 from all exception levels and security + * states when system register trace is implemented. + * When system register trace is not implemented, this bit is RES0 and + * hence set to zero. + * * CPTR_EL3.TTA: Set to zero so that System register accesses to the * trace registers do not trap to EL3. * @@ -201,6 +207,11 @@ */ mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT)) + mrs x1, id_aa64dfr0_el1 + ubfx x1, x1, #ID_AA64DFR0_TRACEVER_SHIFT, #ID_AA64DFR0_TRACEVER_LENGTH + cbz x1, 1f + orr x0, x0, #TTA_BIT +1: msr cptr_el3, x0 /* -- cgit v1.2.3 From d4582d30885673987240cf01fd4f5d2e6780e84c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 29 Jun 2021 11:44:20 +0100 Subject: feat(sys_reg_trace): enable trace system registers access from lower NS ELs Introduced a build flag 'ENABLE_SYS_REG_TRACE_FOR_NS' to enable trace system registers access in NS-EL2, or NS-EL1 (when NS-EL2 is implemented but unused). Change-Id: Idc1acede4186e101758cbf7bed5af7b634d7d18d Signed-off-by: Manish V Badarkhe --- Makefile | 2 ++ bl31/bl31.mk | 4 +++ bl32/sp_min/sp_min.mk | 4 +++ docs/getting_started/build-options.rst | 5 +++ include/arch/aarch32/arch_helpers.h | 1 + include/lib/extensions/sys_reg_trace.h | 18 +++++++++++ lib/el3_runtime/aarch32/context_mgmt.c | 5 +++ lib/el3_runtime/aarch64/context_mgmt.c | 7 ++++ .../sys_reg_trace/aarch32/sys_reg_trace.c | 36 +++++++++++++++++++++ .../sys_reg_trace/aarch64/sys_reg_trace.c | 37 ++++++++++++++++++++++ make_helpers/defaults.mk | 5 +++ 11 files changed, 124 insertions(+) create mode 100644 include/lib/extensions/sys_reg_trace.h create mode 100644 lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c create mode 100644 lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c diff --git a/Makefile b/Makefile index c8ffdab06..5de0e07fa 100644 --- a/Makefile +++ b/Makefile @@ -965,6 +965,7 @@ $(eval $(call assert_booleans,\ ENABLE_FEAT_SB \ PSA_FWU_SUPPORT \ ENABLE_TRBE_FOR_NS \ + ENABLE_SYS_REG_TRACE_FOR_NS \ ))) $(eval $(call assert_numerics,\ @@ -1066,6 +1067,7 @@ $(eval $(call add_defines,\ NR_OF_IMAGES_IN_FW_BANK \ PSA_FWU_SUPPORT \ ENABLE_TRBE_FOR_NS \ + ENABLE_SYS_REG_TRACE_FOR_NS \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index dc3d3c0be..ccd54bb5d 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -94,6 +94,10 @@ ifeq (${ENABLE_TRBE_FOR_NS},1) BL31_SOURCES += lib/extensions/trbe/trbe.c endif +ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) +BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c +endif + ifeq (${WORKAROUND_CVE_2017_5715},1) BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \ lib/cpus/aarch64/wa_cve_2017_5715_mmu.S diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk index 8b5eddd66..486d39d91 100644 --- a/bl32/sp_min/sp_min.mk +++ b/bl32/sp_min/sp_min.mk @@ -42,6 +42,10 @@ BL32_SOURCES += services/std_svc/trng/trng_main.c \ services/std_svc/trng/trng_entropy_pool.c endif +ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) +BL32_SOURCES += lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c +endif + BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S # Include the platform-specific SP_MIN Makefile diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 57b880a9f..15535d4a8 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -781,6 +781,11 @@ Common build options feature for AArch64. The default is 0 and it is automatically disabled when the target architecture is AArch32. +- ``ENABLE_SYS_REG_TRACE_FOR_NS``: Boolean option to enable trace system + registers access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented + but unused). This feature is available if trace unit such as ETMv4.x, and + ETE(extending ETM feature) is implemented. This flag is disabled by default. + GICv3 driver options -------------------- diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index 726baf596..8d628c1d5 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -217,6 +217,7 @@ DEFINE_SYSREG_RW_FUNCS(cpsr) DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR) DEFINE_COPROCR_READ_FUNC(midr, MIDR) DEFINE_COPROCR_READ_FUNC(id_mmfr4, ID_MMFR4) +DEFINE_COPROCR_READ_FUNC(id_dfr0, ID_DFR0) DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0) DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1) DEFINE_COPROCR_READ_FUNC(isr, ISR) diff --git a/include/lib/extensions/sys_reg_trace.h b/include/lib/extensions/sys_reg_trace.h new file mode 100644 index 000000000..74470fee2 --- /dev/null +++ b/include/lib/extensions/sys_reg_trace.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SYS_REG_TRACE_H +#define SYS_REG_TRACE_H + +#include + +#if __aarch64__ +void sys_reg_trace_enable(cpu_context_t *context); +#else +void sys_reg_trace_enable(void); +#endif /* __aarch64__ */ + +#endif /* SYS_REG_TRACE_H */ diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c index 81d793b46..2e5b38ff3 100644 --- a/lib/el3_runtime/aarch32/context_mgmt.c +++ b/lib/el3_runtime/aarch32/context_mgmt.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /******************************************************************************* @@ -136,6 +137,10 @@ static void enable_extensions_nonsecure(bool el2_unused) #if ENABLE_AMU amu_enable(el2_unused); #endif + +#if ENABLE_SYS_REG_TRACE_FOR_NS + sys_reg_trace_enable(); +#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ #endif } diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 9eb66ed84..0eb800a8f 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -354,6 +355,10 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) trbe_enable(); #endif /* ENABLE_TRBE_FOR_NS */ +#if ENABLE_SYS_REG_TRACE_FOR_NS + sys_reg_trace_enable(ctx); +#endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ + #endif } @@ -463,6 +468,8 @@ void cm_prepare_el3_exit(uint32_t security_state) * CPTR_EL2.TTA: Set to zero so that Non-secure System * register accesses to the trace registers from both * Execution states do not trap to EL2. + * If PE trace unit System registers are not implemented + * then this bit is reserved, and must be set to zero. * * CPTR_EL2.TFP: Set to zero so that Non-secure accesses * to SIMD and floating-point functionality from both diff --git a/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c new file mode 100644 index 000000000..89b8029ca --- /dev/null +++ b/lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +static bool sys_reg_trace_supported(void) +{ + uint32_t features; + + features = read_id_dfr0() >> ID_DFR0_COPTRC_SHIFT; + return ((features & ID_DFR0_COPTRC_MASK) == + ID_DFR0_COPTRC_SUPPORTED); +} + +void sys_reg_trace_enable(void) +{ + uint32_t val; + + if (sys_reg_trace_supported()) { + /* + * NSACR.NSTRCDIS = b0 + * enable NS system register access to implemented trace + * registers. + */ + val = read_nsacr(); + val &= ~NSTRCDIS_BIT; + write_nsacr(val); + } +} diff --git a/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c new file mode 100644 index 000000000..960d69842 --- /dev/null +++ b/lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +static bool sys_reg_trace_supported(void) +{ + uint64_t features; + + features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEVER_SHIFT; + return ((features & ID_AA64DFR0_TRACEVER_MASK) == + ID_AA64DFR0_TRACEVER_SUPPORTED); +} + +void sys_reg_trace_enable(cpu_context_t *ctx) +{ + uint64_t val; + + if (sys_reg_trace_supported()) { + /* Retrieve CPTR_EL3 value from the given context 'ctx', + * and update CPTR_EL3.TTA bit to 0. + * This function is called while switching context to NS to + * allow system trace register access to NS-EL2 and NS-EL1 + * when NS-EL2 is implemented but not used. + */ + val = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3); + val &= ~TTA_BIT; + write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, val); + } +} diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index e95d2268f..060bc3864 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -366,3 +366,8 @@ ifneq (${ARCH},aarch32) else override ENABLE_TRBE_FOR_NS := 0 endif + +# By default, disable access of trace system registers from NS lower +# ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if +# system register trace is implemented. +ENABLE_SYS_REG_TRACE_FOR_NS := 0 -- cgit v1.2.3 From 5de20ece38f782c8459f546a08c6a97b9e0f5bc5 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Sun, 18 Jul 2021 02:26:27 +0100 Subject: feat(trf): initialize trap settings of trace filter control registers access Trap bits of trace filter control registers access are in architecturally UNKNOWN state at boot hence 1. Initialized trap bits to one to prohibit trace filter control registers accesses in lower ELs (EL2, EL1) in all security states when FEAT_TRF is implemented. 2. These bits are RES0 when FEAT_TRF is not implemented and hence set it to zero to aligns with the Arm ARM reference recommendation, that mentions software must writes RES0 bits with all 0s. Change-Id: I1b7abf2170ece84ee585c91cda32d22b25c0fc34 Signed-off-by: Manish V Badarkhe --- include/arch/aarch32/arch.h | 5 +++++ include/arch/aarch32/el3_common_macros.S | 15 ++++++++++++++- include/arch/aarch64/arch.h | 4 ++++ include/arch/aarch64/el3_common_macros.S | 13 ++++++++++++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 5b160a227..7221b6273 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -107,6 +107,10 @@ #define ID_DFR0_COPTRC_MASK U(0xf) #define ID_DFR0_COPTRC_SUPPORTED U(1) #define ID_DFR0_COPTRC_LENGTH U(4) +#define ID_DFR0_TRACEFILT_SHIFT U(28) +#define ID_DFR0_TRACEFILT_MASK U(0xf) +#define ID_DFR0_TRACEFILT_SUPPORTED U(1) +#define ID_DFR0_TRACEFILT_LENGTH U(4) /* ID_DFR1_EL1 definitions */ #define ID_DFR1_MTPMU_SHIFT U(0) @@ -179,6 +183,7 @@ #define SDCR_SPD_DISABLE U(0x2) #define SDCR_SPD_ENABLE U(0x3) #define SDCR_SCCD_BIT (U(1) << 23) +#define SDCR_TTRF_BIT (U(1) << 19) #define SDCR_SPME_BIT (U(1) << 17) #define SDCR_RESET_VAL U(0x0) #define SDCR_MTPME_BIT (U(1) << 28) diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 49e8518d3..65f9a8e6b 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -131,9 +131,22 @@ * in Secure state. This bit is RES0 in versions of the architecture * earlier than ARMv8.5, setting it to 1 doesn't have any effect on * them. + * + * SDCR.TTRF: Set to one so that access to trace filter control + * registers in non-monitor mode generate Monitor trap exception, + * unless the access generates a higher priority exception when + * trace filter control(FEAT_TRF) is implemented. + * When FEAT_TRF is not implemented, this bit is RES0. * --------------------------------------------------------------------- */ - ldr r0, =(SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | SDCR_SCCD_BIT) + ldr r0, =((SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE) | \ + SDCR_SCCD_BIT) & ~SDCR_TTRF_BIT) + ldcopr r1, ID_DFR0 + ubfx r1, r1, #ID_DFR0_TRACEFILT_SHIFT, #ID_DFR0_TRACEFILT_LENGTH + cmp r1, #ID_DFR0_TRACEFILT_SUPPORTED + bne 1f + orr r0, r0, #SDCR_TTRF_BIT +1: stcopr r0, SDCR /* --------------------------------------------------------------------- diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 2a3812394..9ea111452 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -193,6 +193,10 @@ #define ID_AA64DFR0_TRACEVER_MASK ULL(0xf) #define ID_AA64DFR0_TRACEVER_SUPPORTED ULL(1) #define ID_AA64DFR0_TRACEVER_LENGTH U(4) +#define ID_AA64DFR0_TRACEFILT_SHIFT U(40) +#define ID_AA64DFR0_TRACEFILT_MASK U(0xf) +#define ID_AA64DFR0_TRACEFILT_SUPPORTED U(1) +#define ID_AA64DFR0_TRACEFILT_LENGTH U(4) /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */ #define ID_AA64DFR0_PMS_SHIFT U(32) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 18fe0de1e..d4965841f 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -132,14 +132,25 @@ * accesses to Trace Buffer control registers at EL2 and EL1 in any * security state generates trap exceptions to EL3. * If FEAT_TRBE is not implemented, these bits are RES0. + * + * MDCR_EL3.TTRF: Set to one so that access to trace filter control + * registers in non-monitor mode generate EL3 trap exception, + * unless the access generates a higher priority exception when trace + * filter control(FEAT_TRF) is implemented. + * When FEAT_TRF is not implemented, this bit is RES0. * --------------------------------------------------------------------- */ mov_imm x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | \ MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \ MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \ MDCR_TDA_BIT | MDCR_TPM_BIT | MDCR_NSTB(MDCR_NSTB_EL1) | \ - MDCR_NSTBE)) + MDCR_NSTBE | MDCR_TTRF_BIT)) + mrs x1, id_aa64dfr0_el1 + ubfx x1, x1, #ID_AA64DFR0_TRACEFILT_SHIFT, #ID_AA64DFR0_TRACEFILT_LENGTH + cbz x1, 1f + orr x0, x0, #MDCR_TTRF_BIT +1: msr mdcr_el3, x0 /* --------------------------------------------------------------------- -- cgit v1.2.3 From 8fcd3d9600bb2cb6809c6fc68f945ce3ad89633d Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 8 Jul 2021 09:33:18 +0100 Subject: feat(trf): enable trace filter control register access from lower NS EL Introduced a build flag 'ENABLE_TRF_FOR_NS' to enable trace filter control registers access in NS-EL2, or NS-EL1 (when NS-EL2 is implemented but unused). Change-Id: If3f53b8173a5573424b9a405a4bd8c206ffdeb8c Signed-off-by: Manish V Badarkhe --- Makefile | 2 ++ bl31/bl31.mk | 4 ++++ bl32/sp_min/sp_min.mk | 4 ++++ docs/getting_started/build-options.rst | 4 ++++ include/arch/aarch32/arch_helpers.h | 1 + include/lib/extensions/trf.h | 12 ++++++++++++ lib/el3_runtime/aarch32/context_mgmt.c | 5 +++++ lib/el3_runtime/aarch64/context_mgmt.c | 5 +++++ lib/extensions/trf/aarch32/trf.c | 35 +++++++++++++++++++++++++++++++++ lib/extensions/trf/aarch64/trf.c | 36 ++++++++++++++++++++++++++++++++++ make_helpers/defaults.mk | 5 +++++ 11 files changed, 113 insertions(+) create mode 100644 include/lib/extensions/trf.h create mode 100644 lib/extensions/trf/aarch32/trf.c create mode 100644 lib/extensions/trf/aarch64/trf.c diff --git a/Makefile b/Makefile index 5de0e07fa..b9b317604 100644 --- a/Makefile +++ b/Makefile @@ -966,6 +966,7 @@ $(eval $(call assert_booleans,\ PSA_FWU_SUPPORT \ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ + ENABLE_TRF_FOR_NS \ ))) $(eval $(call assert_numerics,\ @@ -1068,6 +1069,7 @@ $(eval $(call add_defines,\ PSA_FWU_SUPPORT \ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ + ENABLE_TRF_FOR_NS \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index ccd54bb5d..7819141ef 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -98,6 +98,10 @@ ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) BL31_SOURCES += lib/extensions/sys_reg_trace/aarch64/sys_reg_trace.c endif +ifeq (${ENABLE_TRF_FOR_NS},1) +BL31_SOURCES += lib/extensions/trf/aarch64/trf.c +endif + ifeq (${WORKAROUND_CVE_2017_5715},1) BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \ lib/cpus/aarch64/wa_cve_2017_5715_mmu.S diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk index 486d39d91..6339cf856 100644 --- a/bl32/sp_min/sp_min.mk +++ b/bl32/sp_min/sp_min.mk @@ -46,6 +46,10 @@ ifeq (${ENABLE_SYS_REG_TRACE_FOR_NS},1) BL32_SOURCES += lib/extensions/sys_reg_trace/aarch32/sys_reg_trace.c endif +ifeq (${ENABLE_TRF_FOR_NS},1) +BL32_SOURCES += lib/extensions/trf/aarch32/trf.c +endif + BL32_LINKERFILE := bl32/sp_min/sp_min.ld.S # Include the platform-specific SP_MIN Makefile diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 15535d4a8..a856dbb1a 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -786,6 +786,10 @@ Common build options but unused). This feature is available if trace unit such as ETMv4.x, and ETE(extending ETM feature) is implemented. This flag is disabled by default. +- ``ENABLE_TRF_FOR_NS``: Boolean option to enable trace filter control registers + access from NS ELs, NS-EL2 or NS-EL1 (when NS-EL2 is implemented but unused), + if FEAT_TRF is implemented. This flag is disabled by default. + GICv3 driver options -------------------- diff --git a/include/arch/aarch32/arch_helpers.h b/include/arch/aarch32/arch_helpers.h index 8d628c1d5..033098915 100644 --- a/include/arch/aarch32/arch_helpers.h +++ b/include/arch/aarch32/arch_helpers.h @@ -283,6 +283,7 @@ DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1) DEFINE_COPROCR_RW_FUNCS_64(icc_sgi0r_el1, ICC_SGI0R_EL1_64) DEFINE_COPROCR_WRITE_FUNC_64(icc_sgi1r, ICC_SGI1R_EL1_64) +DEFINE_COPROCR_RW_FUNCS(sdcr, SDCR) DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR) DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL) DEFINE_COPROCR_READ_FUNC(pmcr, PMCR) diff --git a/include/lib/extensions/trf.h b/include/lib/extensions/trf.h new file mode 100644 index 000000000..18f17f36d --- /dev/null +++ b/include/lib/extensions/trf.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TRF_H +#define TRF_H + +void trf_enable(void); + +#endif /* TRF_H */ diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c index 2e5b38ff3..3ef378ce1 100644 --- a/lib/el3_runtime/aarch32/context_mgmt.c +++ b/lib/el3_runtime/aarch32/context_mgmt.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /******************************************************************************* @@ -141,6 +142,10 @@ static void enable_extensions_nonsecure(bool el2_unused) #if ENABLE_SYS_REG_TRACE_FOR_NS sys_reg_trace_enable(); #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ + +#if ENABLE_TRF_FOR_NS + trf_enable(); +#endif /* ENABLE_TRF_FOR_NS */ #endif } diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 0eb800a8f..52102ddd4 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -359,6 +360,10 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) sys_reg_trace_enable(ctx); #endif /* ENABLE_SYS_REG_TRACE_FOR_NS */ +#if ENABLE_TRF_FOR_NS + trf_enable(); +#endif /* ENABLE_TRF_FOR_NS */ + #endif } diff --git a/lib/extensions/trf/aarch32/trf.c b/lib/extensions/trf/aarch32/trf.c new file mode 100644 index 000000000..834092d5a --- /dev/null +++ b/lib/extensions/trf/aarch32/trf.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +static bool trf_supported(void) +{ + uint32_t features; + + features = read_id_dfr0() >> ID_DFR0_TRACEFILT_SHIFT; + return ((features & ID_DFR0_TRACEFILT_MASK) == + ID_DFR0_TRACEFILT_SUPPORTED); +} + +void trf_enable(void) +{ + uint32_t val; + + if (trf_supported()) { + /* + * Allow access of trace filter control registers from + * non-monitor mode + */ + val = read_sdcr(); + val &= ~SDCR_TTRF_BIT; + write_sdcr(val); + } +} diff --git a/lib/extensions/trf/aarch64/trf.c b/lib/extensions/trf/aarch64/trf.c new file mode 100644 index 000000000..1da5dcee0 --- /dev/null +++ b/lib/extensions/trf/aarch64/trf.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +static bool trf_supported(void) +{ + uint64_t features; + + features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_TRACEFILT_SHIFT; + return ((features & ID_AA64DFR0_TRACEFILT_MASK) == + ID_AA64DFR0_TRACEFILT_SUPPORTED); +} + +void trf_enable(void) +{ + uint64_t val; + + if (trf_supported()) { + /* + * MDCR_EL3.TTRF = b0 + * Allow access of trace filter control registers from NS-EL2 + * and NS-EL1 when NS-EL2 is implemented but not used + */ + val = read_mdcr_el3(); + val &= ~MDCR_TTRF_BIT; + write_mdcr_el3(val); + } +} diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 060bc3864..c1886218d 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -371,3 +371,8 @@ endif # ELs i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused if # system register trace is implemented. ENABLE_SYS_REG_TRACE_FOR_NS := 0 + +# By default, disable trace filter control registers access to NS +# lower ELs, i.e. NS-EL2, or NS-EL1 if NS-EL2 implemented but unused +# if FEAT_TRF is implemented. +ENABLE_TRF_FOR_NS := 0 -- cgit v1.2.3 From cd3f0ae6f855b2998bc09e5c3a458528c92acb90 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 24 Aug 2021 14:42:35 +0100 Subject: feat(plat/fvp): enable trace extension features by default Signed-off-by: Manish V Badarkhe Change-Id: I3e344b0abda7ab4e54ee918ec65ff39d40855fcd --- plat/arm/board/fvp/platform.mk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 3c70eede3..2f8a65e56 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -378,3 +378,12 @@ endif # dynamically if TRUSTED_BOARD_BOOT is set. DYN_DISABLE_AUTH := 1 endif + +# enable trace buffer control registers access to NS by default +ENABLE_TRBE_FOR_NS := 1 + +# enable trace system registers access to NS by default +ENABLE_SYS_REG_TRACE_FOR_NS := 1 + +# enable trace filter control registers access to NS by default +ENABLE_TRF_FOR_NS := 1 -- cgit v1.2.3 From a669983c78828e3f4a4f14b9e5a6ee79dcfde20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 27 Aug 2021 11:16:43 +0200 Subject: fix(drivers/marvell/comphy): fix name of 3.125G SerDes mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no support for 2.5/3.125G SGMII. This 3.125G SerDes mode is not SGMII. It is just plain 1000Base-X (as defined in IEEE 802.3z standard) but upclocked 2.5x. This mode is commonly known under name 2500Base-X. So remove incorrect SGMII keyword from names and comments and replace it by more adequate 2500Base-X keyword. There is no functional change in code, just renaming macros and updating comments. Signed-off-by: Pali Rohár Change-Id: If79aec16cc233f4896aafd75bfbbebb3f172a197 --- drivers/marvell/comphy/comphy-cp110.h | 2 +- drivers/marvell/comphy/phy-comphy-3700.c | 14 +++++++------- drivers/marvell/comphy/phy-comphy-common.h | 2 +- drivers/marvell/comphy/phy-comphy-cp110.c | 22 +++++++++++----------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h index 9b10619ed..af5c71518 100644 --- a/drivers/marvell/comphy/comphy-cp110.h +++ b/drivers/marvell/comphy/comphy-cp110.h @@ -54,7 +54,7 @@ #define COMMON_SELECTOR_PIPE_COMPHY_USBH 0x1 #define COMMON_SELECTOR_PIPE_COMPHY_USBD 0x2 -/* SGMII/HS-SGMII/SFI/RXAUI */ +/* SGMII/Base-X/SFI/RXAUI */ #define COMMON_SELECTOR_COMPHY0_1_2_NETWORK 0x1 #define COMMON_SELECTOR_COMPHY3_RXAUI 0x1 #define COMMON_SELECTOR_COMPHY3_SGMII 0x2 diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 7377e5e3d..027d07d17 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -135,7 +135,7 @@ static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index, break; case (COMPHY_SGMII_MODE): - case (COMPHY_HS_SGMII_MODE): + case (COMPHY_2500BASEX_MODE): if (comphy_index == COMPHY_LANE0) reg &= ~COMPHY_SELECTOR_USB3_GBE1_SEL_BIT; else if (comphy_index == COMPHY_LANE1) @@ -183,7 +183,7 @@ error: * with COMPHY_USB3D_MODE or COMPHY_USB3H_MODE. (The usb3 phy initialization * code does not differentiate between these modes.) * Also it returns COMPHY_SGMII_MODE even if the phy was configures with - * COMPHY_HS_SGMII_MODE. (The sgmii phy initialization code does differentiate + * COMPHY_2500BASEX_MODE. (The sgmii phy initialization code does differentiate * between these modes, but it is irrelevant when powering the phy off.) */ static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index) @@ -401,8 +401,8 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, /* SGMII 1G, SerDes speed 1.25G */ data |= SD_SPEED_1_25_G << GEN_RX_SEL_OFFSET; data |= SD_SPEED_1_25_G << GEN_TX_SEL_OFFSET; - } else if (mode == COMPHY_HS_SGMII_MODE) { - /* HS SGMII (2.5G), SerDes speed 3.125G */ + } else if (mode == COMPHY_2500BASEX_MODE) { + /* 2500Base-X, SerDes speed 3.125G */ data |= SD_SPEED_2_5_G << GEN_RX_SEL_OFFSET; data |= SD_SPEED_2_5_G << GEN_TX_SEL_OFFSET; } else { @@ -479,7 +479,7 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, * 25 MHz the default values stored in PHY registers are OK. */ debug("Running C-DPI phy init %s mode\n", - mode == COMPHY_HS_SGMII_MODE ? "2G5" : "1G"); + mode == COMPHY_2500BASEX_MODE ? "2G5" : "1G"); if (get_ref_clk() == 40) comphy_sgmii_phy_init(comphy_index, mode, sd_ip_addr); @@ -883,7 +883,7 @@ int mvebu_3700_comphy_power_on(uint8_t comphy_index, uint32_t comphy_mode) comphy_mode); break; case(COMPHY_SGMII_MODE): - case(COMPHY_HS_SGMII_MODE): + case(COMPHY_2500BASEX_MODE): ret = mvebu_a3700_comphy_sgmii_power_on(comphy_index, comphy_mode); break; @@ -960,7 +960,7 @@ int mvebu_3700_comphy_power_off(uint8_t comphy_index, uint32_t comphy_mode) switch (mode) { case(COMPHY_SGMII_MODE): - case(COMPHY_HS_SGMII_MODE): + case(COMPHY_2500BASEX_MODE): err = mvebu_a3700_comphy_sgmii_power_off(comphy_index); break; case (COMPHY_USB3_MODE): diff --git a/drivers/marvell/comphy/phy-comphy-common.h b/drivers/marvell/comphy/phy-comphy-common.h index e3b430a91..c599437a3 100644 --- a/drivers/marvell/comphy/phy-comphy-common.h +++ b/drivers/marvell/comphy/phy-comphy-common.h @@ -87,7 +87,7 @@ #define COMPHY_SATA_MODE 0x1 #define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */ -#define COMPHY_HS_SGMII_MODE 0x3 /* SGMII 2.5G */ +#define COMPHY_2500BASEX_MODE 0x3 /* 2500Base-X */ #define COMPHY_USB3H_MODE 0x4 #define COMPHY_USB3D_MODE 0x5 #define COMPHY_PCIE_MODE 0x6 diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index 86f4c77c5..d10425b36 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -30,7 +30,7 @@ /* COMPHY speed macro */ #define COMPHY_SPEED_1_25G 0 /* SGMII 1G */ #define COMPHY_SPEED_2_5G 1 -#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */ +#define COMPHY_SPEED_3_125G 2 /* 2500Base-X */ #define COMPHY_SPEED_5G 3 #define COMPHY_SPEED_5_15625G 4 /* XFI 5G */ #define COMPHY_SPEED_6G 5 @@ -191,7 +191,7 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base, case(3): /* For comphy 3: * 0x1 = RXAUI_Lane1 - * 0x2 = SGMII/HS-SGMII Port1 + * 0x2 = SGMII/Base-X Port1 */ if (mode == COMPHY_RXAUI_MODE) reg |= COMMON_SELECTOR_COMPHY3_RXAUI << @@ -202,20 +202,20 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base, break; case(4): /* For comphy 4: - * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1 - * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0 + * 0x1 = SGMII/Base-X Port1, XFI1/SFI1 + * 0x2 = SGMII/Base-X Port0: XFI0/SFI0, RXAUI_Lane0 * - * We want to check if SGMII1/HS_SGMII1 is the + * We want to check if SGMII1 is the * requested mode in order to determine which value * should be set (all other modes use the same value) * so we need to strip the mode, and check the ID - * because we might handle SGMII0/HS_SGMII0 too. + * because we might handle SGMII0 too. */ /* TODO: need to distinguish between CP110 and CP115 * as SFI1/XFI1 available only for CP115. */ if ((mode == COMPHY_SGMII_MODE || - mode == COMPHY_HS_SGMII_MODE || + mode == COMPHY_2500BASEX_MODE || mode == COMPHY_SFI_MODE || mode == COMPHY_XFI_MODE || mode == COMPHY_AP_MODE) @@ -228,7 +228,7 @@ static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base, break; case(5): /* For comphy 5: - * 0x1 = SGMII/HS-SGMII Port2 + * 0x1 = SGMII/Base-X Port2 * 0x2 = RXAUI Lane1 */ if (mode == COMPHY_RXAUI_MODE) @@ -713,7 +713,7 @@ static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base, data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; } else if (sgmii_speed == COMPHY_SPEED_3_125G) { - /* HS SGMII (2.5G), SerDes speed 3.125G */ + /* 2500Base-X, SerDes speed 3.125G */ data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; } else { @@ -2343,7 +2343,7 @@ int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, switch (mode) { case (COMPHY_SGMII_MODE): - case (COMPHY_HS_SGMII_MODE): + case (COMPHY_2500BASEX_MODE): case (COMPHY_XFI_MODE): case (COMPHY_SFI_MODE): case (COMPHY_RXAUI_MODE): @@ -2378,7 +2378,7 @@ int mvebu_cp110_comphy_power_on(uint64_t comphy_base, comphy_mode); break; case(COMPHY_SGMII_MODE): - case(COMPHY_HS_SGMII_MODE): + case(COMPHY_2500BASEX_MODE): err = mvebu_cp110_comphy_sgmii_power_on(comphy_base, comphy_index, comphy_mode); -- cgit v1.2.3 From 1fe27d71353dd35f60555012c5ace246836517cc Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 24 Aug 2021 10:02:52 +0100 Subject: refactor(gic): move GIC IIDR numbers For the GIC power management we need to identify certain GIC implementations, so we have the IIDR values for some Arm Ltd. GIC models defined. We will need those number elsewhere very soon, so export them to a shared header file, to avoid defining them again. Change-Id: I1b8e2d93d6cea0d066866143c89eef736231134f Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gic-x00.c | 4 +--- include/drivers/arm/arm_gicv3_common.h | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/arm/gic/v3/gic-x00.c b/drivers/arm/gic/v3/gic-x00.c index eccfd976f..aaef485ff 100644 --- a/drivers/arm/gic/v3/gic-x00.c +++ b/drivers/arm/gic/v3/gic-x00.c @@ -16,15 +16,13 @@ #include #include +#include #include #include "gicv3_private.h" /* GIC-600 specific register offsets */ #define GICR_PWRR 0x24U -#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) -#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) -#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) /* GICR_PWRR fields */ #define PWRR_RDPD_SHIFT 0 diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h index b88b59fbf..e5df31136 100644 --- a/include/drivers/arm/arm_gicv3_common.h +++ b/include/drivers/arm/arm_gicv3_common.h @@ -17,4 +17,8 @@ #define WAKER_SL_BIT (1U << WAKER_SL_SHIFT) #define WAKER_QSC_BIT (1U << WAKER_QSC_SHIFT) +#define IIDR_MODEL_ARM_GIC_600 U(0x0200043b) +#define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) +#define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) + #endif /* ARM_GICV3_COMMON_H */ -- cgit v1.2.3 From feb7081863f454b9e465efc074ca669f7a4c783d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 18 May 2021 15:46:58 +0100 Subject: feat(gicv3): multichip: detect GIC-700 at runtime At the moment we have a GIC_ENABLE_V4_EXTN build time variable to determine whether the GIC interrupt controller is compliant to version 4.0 of the GIC spec or not. In case of the GIC-600 multichip support we were somewhat abusing that flag to differentiate between a GIC-700 and GIC-600 implementation being used in the system. To avoid a build time dependency on this flag, look at the GICD_IIDR register and check if the hardware is a GIC-600 or not, to make this decision at runtime. We then use the values for either GIC-700 or the GIC-600, respectively. Change-Id: I8c09ec1cd6fd60d28da879ed55ffef5506f9869d Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gic600_multichip.c | 22 ++++++++++++++++++++-- drivers/arm/gic/v3/gic600_multichip_private.h | 26 ++++++++++++-------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c index ca7c43bf9..fd3d8c207 100644 --- a/drivers/arm/gic/v3/gic600_multichip.c +++ b/drivers/arm/gic/v3/gic600_multichip.c @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -73,6 +74,7 @@ static void set_gicd_chipr_n(uintptr_t base, unsigned int spi_id_max) { unsigned int spi_block_min, spi_blocks; + unsigned int gicd_iidr_val = gicd_read_iidr(base); uint64_t chipr_n_val; /* @@ -100,8 +102,24 @@ static void set_gicd_chipr_n(uintptr_t base, spi_block_min = SPI_BLOCK_MIN_VALUE(spi_id_min); spi_blocks = SPI_BLOCKS_VALUE(spi_id_min, spi_id_max); - chipr_n_val = (GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks)) | - GICD_CHIPRx_SOCKET_STATE; + switch ((gicd_iidr_val & IIDR_MODEL_MASK)) { + case IIDR_MODEL_ARM_GIC_600: + chipr_n_val = GICD_CHIPR_VALUE_GIC_600(chip_addr, + spi_block_min, + spi_blocks); + break; + case IIDR_MODEL_ARM_GIC_700: + chipr_n_val = GICD_CHIPR_VALUE_GIC_700(chip_addr, + spi_block_min, + spi_blocks); + break; + default: + ERROR("Unsupported GIC model 0x%x for multichip setup.\n", + gicd_iidr_val); + panic(); + break; + } + chipr_n_val |= GICD_CHIPRx_SOCKET_STATE; /* * Wait for DCHIPR.PUP to be zero before commencing writes to diff --git a/drivers/arm/gic/v3/gic600_multichip_private.h b/drivers/arm/gic/v3/gic600_multichip_private.h index 27b8e817f..5d1ff6a19 100644 --- a/drivers/arm/gic/v3/gic600_multichip_private.h +++ b/drivers/arm/gic/v3/gic600_multichip_private.h @@ -27,17 +27,11 @@ #define GICD_CHIPSR_RTS_SHIFT 4 #define GICD_DCHIPR_RT_OWNER_SHIFT 4 -/* - * If GIC v4 extension is enabled, then use SPI macros specific to GIC-700. - * Other shifts and mask remains same between GIC-600 and GIC-700. - */ -#if GIC_ENABLE_V4_EXTN -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 9 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 3 -#else -#define GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT 10 -#define GICD_CHIPRx_SPI_BLOCKS_SHIFT 5 -#endif +/* Other shifts and masks remain the same between GIC-600 and GIC-700. */ +#define GIC_700_SPI_BLOCK_MIN_SHIFT 9 +#define GIC_700_SPI_BLOCKS_SHIFT 3 +#define GIC_600_SPI_BLOCK_MIN_SHIFT 10 +#define GIC_600_SPI_BLOCKS_SHIFT 5 #define GICD_CHIPSR_RTS_STATE_DISCONNECTED U(0) #define GICD_CHIPSR_RTS_STATE_UPDATING U(1) @@ -59,10 +53,14 @@ #define SPI_BLOCKS_VALUE(spi_id_min, spi_id_max) \ (((spi_id_max) - (spi_id_min) + 1) / \ GIC600_SPI_ID_MIN) -#define GICD_CHIPR_VALUE(chip_addr, spi_block_min, spi_blocks) \ +#define GICD_CHIPR_VALUE_GIC_700(chip_addr, spi_block_min, spi_blocks) \ + (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \ + ((spi_block_min) << GIC_700_SPI_BLOCK_MIN_SHIFT) | \ + ((spi_blocks) << GIC_700_SPI_BLOCKS_SHIFT)) +#define GICD_CHIPR_VALUE_GIC_600(chip_addr, spi_block_min, spi_blocks) \ (((chip_addr) << GICD_CHIPRx_ADDR_SHIFT) | \ - ((spi_block_min) << GICD_CHIPRx_SPI_BLOCK_MIN_SHIFT) | \ - ((spi_blocks) << GICD_CHIPRx_SPI_BLOCKS_SHIFT)) + ((spi_block_min) << GIC_600_SPI_BLOCK_MIN_SHIFT) | \ + ((spi_blocks) << GIC_600_SPI_BLOCKS_SHIFT)) /* * Multichip data assertion macros -- cgit v1.2.3 From 858f40e379684fefc8b52c7b9e60576bc3794a69 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 18 May 2021 15:51:06 +0100 Subject: feat(gicv3): detect GICv4 feature at runtime At the moment we have a GIC_ENABLE_V4_EXTN build time variable to determine whether the GIC interrupt controller is compliant to version 4.0 of the spec or not. This just changes the number of 64K MMIO pages we expect per redistributor. To support firmware builds which run on variable systems (emulators, fast model or FPGAs), let's make this decision at runtime. The GIC specification provides several architected flags to learn the size of the MMIO frame per redistributor, we use GICR_TYPER[VLPI] here. Provide a (static inline) function to return the size of each redistributor. We keep the GIC_ENABLE_V4_EXTN build time variable around, but change its meaning to enable this autodetection code. Systems not defining this rely on a "pure" GICv3 (as before), but platforms setting it to "1" can now deal with both configurations. Change-Id: I9ede4acf058846157a0a9e2ef6103bf07c7655d9 Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gicv3_helpers.c | 11 ++++++----- drivers/arm/gic/v3/gicv3_main.c | 10 ++-------- include/drivers/arm/gicv3.h | 22 +++++++++++++++++----- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index a0f44e966..d752013e2 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -86,8 +86,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, if (proc_num < rdistif_num) { rdistif_base_addrs[proc_num] = rdistif_base; } - - rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } while ((typer_val & TYPER_LAST_BIT) == 0U); } @@ -383,11 +382,13 @@ unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame) uintptr_t rdistif_base = gicr_frame; unsigned int count; - for (count = 1; count < PLATFORM_CORE_COUNT; count++) { - if ((gicr_read_typer(rdistif_base) & TYPER_LAST_BIT) != 0U) { + for (count = 1U; count < PLATFORM_CORE_COUNT; count++) { + uint64_t typer_val = gicr_read_typer(rdistif_base); + + if ((typer_val & TYPER_LAST_BIT) != 0U) { break; } - rdistif_base += (1U << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } return count; diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index b1139b5e9..53a8fae3b 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -123,13 +123,7 @@ void __init gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data) gic_version &= PIDR2_ARCH_REV_MASK; /* Check GIC version */ -#if GIC_ENABLE_V4_EXTN - assert(gic_version == ARCH_REV_GICV4); - - /* GICv4 supports Direct Virtual LPI injection */ - assert((gicd_read_typer(plat_driver_data->gicd_base) - & TYPER_DVIS) != 0); -#else +#if !GIC_ENABLE_V4_EXTN assert(gic_version == ARCH_REV_GICV3); #endif /* @@ -1298,7 +1292,7 @@ int gicv3_rdistif_probe(const uintptr_t gicr_frame) gicr_frame_found = true; break; } - rdistif_base += (uintptr_t)(ULL(1) << GICR_PCPUBASE_SHIFT); + rdistif_base += gicv3_redist_size(typer_val); } while ((typer_val & TYPER_LAST_BIT) == 0U); if (!gicr_frame_found) { diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index d8ac4cb33..fa8946b16 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -153,11 +153,8 @@ /******************************************************************************* * Common GIC Redistributor interface registers & constants ******************************************************************************/ -#if GIC_ENABLE_V4_EXTN -#define GICR_PCPUBASE_SHIFT 0x12 -#else -#define GICR_PCPUBASE_SHIFT 0x11 -#endif +#define GICR_V4_PCPUBASE_SHIFT 0x12 +#define GICR_V3_PCPUBASE_SHIFT 0x11 #define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ #define GICR_CTLR U(0x0) #define GICR_IIDR U(0x04) @@ -212,12 +209,14 @@ #define TYPER_AFF_VAL_SHIFT 32 #define TYPER_PROC_NUM_SHIFT 8 #define TYPER_LAST_SHIFT 4 +#define TYPER_VLPI_SHIFT 1 #define TYPER_AFF_VAL_MASK U(0xffffffff) #define TYPER_PROC_NUM_MASK U(0xffff) #define TYPER_LAST_MASK U(0x1) #define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT) +#define TYPER_VLPI_BIT BIT_32(TYPER_VLPI_SHIFT) #define TYPER_PPI_NUM_SHIFT U(27) #define TYPER_PPI_NUM_MASK U(0x1f) @@ -312,6 +311,19 @@ #include #include +static inline uintptr_t gicv3_redist_size(uint64_t typer_val) +{ +#if GIC_ENABLE_V4_EXTN + if ((typer_val & TYPER_VLPI_BIT) != 0U) { + return 1U << GICR_V4_PCPUBASE_SHIFT; + } else { + return 1U << GICR_V3_PCPUBASE_SHIFT; + } +#else + return 1U << GICR_V3_PCPUBASE_SHIFT; +#endif +} + static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) { return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT); diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index a5f5ea0f3..1c015d51e 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -218,7 +218,7 @@ static void fpga_prepare_dtb(void) INFO("Adjusting GICR DT region to cover %u cores\n", nr_cores); err = fdt_adjust_gic_redist(fdt, nr_cores, - 1U << GICR_PCPUBASE_SHIFT); + 1U << GICR_V3_PCPUBASE_SHIFT); if (err < 0) { ERROR("Error %d fixing up GIC DT node\n", err); } -- cgit v1.2.3 From c69f815b09ab85d3ace8fd2979ffafb1184ec76c Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 18 May 2021 15:53:05 +0100 Subject: feat(arm_fpga): support GICv4 images Up until now we relied on the GICs used in our FPGA images to be GICv3 compliant, without the "direct virtual injection" feature (aka GICv4) enabled. To support newer images which have GICv4 compliant GICs, enable the newly introduced GICv4 detection code, and use that also when we adjust the redistributor region size in the devicetree. This allows the same BL31 image to be used with GICv3 or GICv4 FPGA images. Change-Id: I9f6435a6d5150983625efe3650a8b7d1ef11b1d1 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 2 +- plat/arm/board/arm_fpga/fpga_gicv3.c | 9 +++++++++ plat/arm/board/arm_fpga/fpga_private.h | 1 + plat/arm/board/arm_fpga/platform.mk | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 1c015d51e..81d040cba 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -218,7 +218,7 @@ static void fpga_prepare_dtb(void) INFO("Adjusting GICR DT region to cover %u cores\n", nr_cores); err = fdt_adjust_gic_redist(fdt, nr_cores, - 1U << GICR_V3_PCPUBASE_SHIFT); + fpga_get_redist_size()); if (err < 0) { ERROR("Error %d fixing up GIC DT node\n", err); } diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c index bfc116bef..4a97beb96 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -82,3 +83,11 @@ unsigned int fpga_get_nr_gic_cores(void) { return gicv3_rdistif_get_number_frames(fpga_gicv3_driver_data.gicr_base); } + +uintptr_t fpga_get_redist_size(void) +{ + uint64_t typer_val = mmio_read_64(fpga_gicv3_driver_data.gicr_base + + GICR_TYPER); + + return gicv3_redist_size(typer_val); +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 1ca241f26..cc809c4e4 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -25,6 +25,7 @@ void fpga_pwr_gic_on_finish(void); void fpga_pwr_gic_off(void); unsigned int plat_fpga_calc_core_pos(uint32_t mpid); unsigned int fpga_get_nr_gic_cores(void); +uintptr_t fpga_get_redist_size(void); #endif /* __ASSEMBLER__ */ diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index f80ea2fef..baffbcf62 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -89,6 +89,8 @@ endif # Allow detection of GIC-600 GICV3_SUPPORT_GIC600 := 1 +GIC_ENABLE_V4_EXTN := 1 + # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk -- cgit v1.2.3 From 2c248ade2e958eed33127b4ea767fbb7499f31a7 Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Tue, 4 May 2021 16:14:09 -0700 Subject: feat(gic600ae): introduce support for Fault Management Unit The FMU is part of the GIC Distributor (GICD) component. It implements the following functionality in GIC-600AE: * Provides software the means to enable or disable a Safety Mechanism within a GIC block. * Receives error signaling from all Safety Mechanisms within other GIC blocks. * Maintains error records for each GIC block, for software inspection and provides information on the source of the error. * Retains error records across functional reset. * Enables software error recovery testing by providing error injection capabilities in a Safety Mechanism. This patch introduces support to enable error detection for all safety mechanisms provided by the FMU. Platforms are expected to invoke the initialization function during cold boot. The support for the FMU is guarded by the GICV3_SUPPORT_GIC600AE_FMU makefile variable. The default value of this variable is '0'. Change-Id: I421c3d059624ddefd174cb1140a2d2a2296be0c6 Signed-off-by: Varun Wadekar --- docs/getting_started/build-options.rst | 5 + drivers/arm/gic/v3/gic600ae_fmu.c | 244 ++++++++++++++++++++++++++++ drivers/arm/gic/v3/gic600ae_fmu_helpers.c | 257 ++++++++++++++++++++++++++++++ drivers/arm/gic/v3/gicv3.mk | 11 ++ include/drivers/arm/gic600ae_fmu.h | 148 +++++++++++++++++ 5 files changed, 665 insertions(+) create mode 100644 drivers/arm/gic/v3/gic600ae_fmu.c create mode 100644 drivers/arm/gic/v3/gic600ae_fmu_helpers.c create mode 100644 include/drivers/arm/gic600ae_fmu.h diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 901a72a9b..bac884707 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -790,6 +790,11 @@ makefile: GIC-600, so is safe to select even for a GIC500 implementation. This option defaults to 0. +- ``GICV3_SUPPORT_GIC600AE_FMU``: Add support for the Fault Management Unit + for GIC-600 AE. Enabling this option will introduce support to initialize + the FMU. Platforms should call the init function during boot to enable the + FMU and its safety mechanisms. This option defaults to 0. + - ``GICV3_IMPL_GIC600_MULTICHIP``: Selects GIC-600 variant with multichip functionality. This option defaults to 0 diff --git a/drivers/arm/gic/v3/gic600ae_fmu.c b/drivers/arm/gic/v3/gic600ae_fmu.c new file mode 100644 index 000000000..13979fa4d --- /dev/null +++ b/drivers/arm/gic/v3/gic600ae_fmu.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2021, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Driver for GIC-600AE Fault Management Unit + */ + +#include + +#include +#include +#include +#include + +/* GIC-600 AE FMU specific register offsets */ + +/* GIC-600 AE FMU specific macros */ +#define FMU_ERRIDR_NUM U(44) +#define FMU_ERRIDR_NUM_MASK U(0xFFFF) + +/* Safety mechanisms for GICD block */ +static char *gicd_sm_info[] = { + "Reserved", + "GICD dual lockstep error", + "GICD AXI4 slave interface error", + "GICD-PPI AXI4-Stream interface error", + "GICD-ITS AXI4-Stream interface error", + "GICD-SPI-Collator AXI4-Stream interface error", + "GICD AXI4 master interface error", + "SPI RAM DED error", + "SGI RAM DED error", + "Reserved", + "LPI RAM DED error", + "GICD-remote-GICD AXI4-Stream interface error", + "GICD Q-Channel interface error", + "GICD P-Channel interface error", + "SPI RAM address decode error", + "SGI RAM address decode error", + "Reserved", + "LPI RAM address decode error", + "FMU dual lockstep error", + "FMU ping ACK error", + "FMU APB parity error", + "GICD-Wake AXI4-Stream interface error", + "GICD PageOffset or Chip ID error", + "MBIST REQ error", + "SPI RAM SEC error", + "SGI RAM SEC error", + "Reserved", + "LPI RAM SEC error", + "User custom SM0 error", + "User custom SM1 error", + "GICD-ITS Monolithic switch error", + "GICD-ITS Q-Channel interface error", + "GICD-ITS Monolithic interface error", + "GICD FMU ClkGate override" +}; + +/* Safety mechanisms for PPI block */ +static char *ppi_sm_info[] = { + "Reserved", + "PPI dual lockstep error", + "PPI-GICD AXI4-Stream interface error", + "PPI-CPU-IF AXI4-Stream interface error", + "PPI Q-Channel interface error", + "PPI RAM DED error", + "PPI RAM address decode error", + "PPI RAM SEC error", + "PPI User0 SM", + "PPI User1 SM", + "MBIST REQ error", + "PPI interrupt parity protection error", + "PPI FMU ClkGate override" +}; + +/* Safety mechanisms for ITS block */ +static char *its_sm_info[] = { + "Reserved", + "ITS dual lockstep error", + "ITS-GICD AXI4-Stream interface error", + "ITS AXI4 slave interface error", + "ITS AXI4 master interface error", + "ITS Q-Channel interface error", + "ITS RAM DED error", + "ITS RAM address decode error", + "Bypass ACE switch error", + "ITS RAM SEC error", + "ITS User0 SM", + "ITS User1 SM", + "ITS-GICD Monolithic interface error", + "MBIST REQ error", + "ITS FMU ClkGate override" +}; + +/* Safety mechanisms for SPI Collator block */ +static char *spicol_sm_info[] = { + "Reserved", + "SPI Collator dual lockstep error", + "SPI-Collator-GICD AXI4-Stream interface error", + "SPI Collator Q-Channel interface error", + "SPI Collator Q-Channel clock error", + "SPI interrupt parity error" +}; + +/* Safety mechanisms for Wake Request block */ +static char *wkrqst_sm_info[] = { + "Reserved", + "Wake dual lockstep error", + "Wake-GICD AXI4-Stream interface error" +}; + +/* + * Initialization sequence for the FMU + * + * 1. enable error detection for error records that are passed in the blk_present_mask + * 2. enable MBIST REQ and FMU Clk Gate override safety mechanisms for error records + * that are present on the platform + * + * The platforms are expected to pass `errctlr_ce_en` and `errctlr_ue_en`. + */ +void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, + bool errctlr_ce_en, bool errctlr_ue_en) +{ + unsigned int num_blk = gic_fmu_read_erridr(base) & FMU_ERRIDR_NUM_MASK; + uint64_t errctlr; + uint32_t smen; + + INFO("GIC600-AE FMU supports %d error records\n", num_blk); + + assert(num_blk == FMU_ERRIDR_NUM); + + /* sanitize block present mask */ + blk_present_mask &= FMU_BLK_PRESENT_MASK; + + /* Enable error detection for all error records */ + for (unsigned int i = 0U; i < num_blk; i++) { + + /* Skip next steps if the block is not present */ + if ((blk_present_mask & BIT(i)) == 0U) { + continue; + } + + /* Read the error record control register */ + errctlr = gic_fmu_read_errctlr(base, i); + + /* Enable error reporting and logging, if it is disabled */ + if ((errctlr & FMU_ERRCTLR_ED_BIT) == 0U) { + errctlr |= FMU_ERRCTLR_ED_BIT; + } + + /* Enable client provided ERRCTLR settings */ + errctlr |= (errctlr_ce_en ? (FMU_ERRCTLR_CI_BIT | FMU_ERRCTLR_CE_EN_BIT) : 0); + errctlr |= (errctlr_ue_en ? FMU_ERRCTLR_UI_BIT : 0U); + + gic_fmu_write_errctlr(base, i, errctlr); + } + + /* + * Enable MBIST REQ error and FMU CLK gate override safety mechanisms for + * all blocks + * + * GICD, SMID 23 and SMID 33 + * PPI, SMID 10 and SMID 12 + * ITS, SMID 13 and SMID 14 + */ + if ((blk_present_mask & BIT(FMU_BLK_GICD)) != 0U) { + smen = (GICD_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) | + (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + + smen = (GICD_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) | + (FMU_BLK_GICD << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + } + + for (unsigned int i = FMU_BLK_PPI0; i < FMU_BLK_PPI31; i++) { + if ((blk_present_mask & BIT(i)) != 0U) { + smen = (PPI_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) | + (i << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + + smen = (PPI_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) | + (i << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + } + } + + for (unsigned int i = FMU_BLK_ITS0; i < FMU_BLK_ITS7; i++) { + if ((blk_present_mask & BIT(i)) != 0U) { + smen = (ITS_MBIST_REQ_ERROR << FMU_SMEN_SMID_SHIFT) | + (i << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + + smen = (ITS_FMU_CLKGATE_ERROR << FMU_SMEN_SMID_SHIFT) | + (i << FMU_SMEN_BLK_SHIFT); + gic_fmu_write_smen(base, smen); + } + } +} + +/* + * This function enable the GICD background ping engine. The GICD sends ping + * messages to each remote GIC block, and expects a PING_ACK back within the + * specified timeout. Pings need to be enabled after programming the timeout + * value. + */ +void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask, + unsigned int timeout_val, unsigned int interval_diff) +{ + /* + * Populate the PING Mask to skip a specific block while generating + * background ping messages and enable the ping mechanism. + */ + gic_fmu_write_pingmask(base, ~blk_present_mask); + gic_fmu_write_pingctlr(base, (interval_diff << FMU_PINGCTLR_INTDIFF_SHIFT) | + (timeout_val << FMU_PINGCTLR_TIMEOUTVAL_SHIFT) | FMU_PINGCTLR_EN_BIT); +} + +/* Print the safety mechanism description for a given block */ +void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid) +{ + if (blk == FMU_BLK_GICD && smid <= FMU_SMID_GICD_MAX) { + INFO("GICD, SMID %d: %s\n", smid, gicd_sm_info[smid]); + } + + if (blk == FMU_BLK_SPICOL && smid <= FMU_SMID_SPICOL_MAX) { + INFO("SPI Collator, SMID %d: %s\n", smid, spicol_sm_info[smid]); + } + + if (blk == FMU_BLK_WAKERQ && (smid <= FMU_SMID_WAKERQ_MAX)) { + INFO("Wake Request, SMID %d: %s\n", smid, wkrqst_sm_info[smid]); + } + + if (((blk >= FMU_BLK_ITS0) && (blk <= FMU_BLK_ITS7)) && (smid <= FMU_SMID_ITS_MAX)) { + INFO("ITS, SMID %d: %s\n", smid, its_sm_info[smid]); + } + + if (((blk >= FMU_BLK_PPI0) && (blk <= FMU_BLK_PPI31)) && (smid <= FMU_SMID_PPI_MAX)) { + INFO("PPI, SMID %d: %s\n", smid, ppi_sm_info[smid]); + } +} diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c new file mode 100644 index 000000000..84f72925c --- /dev/null +++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2021, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#define GICFMU_IDLE_TIMEOUT_US U(2000000) + +/* Macro to write 32-bit FMU registers */ +#define GIC_FMU_WRITE_32(base, reg, val) \ + do { \ + /* \ + * This register receives the unlock key that is required for \ + * writes to FMU registers to be successful. \ + */ \ + mmio_write_32(base + GICFMU_KEY, 0xBE); \ + /* Perform the actual write */ \ + mmio_write_32((base) + (reg), (val)); \ + } while (false) + +/* Macro to write 64-bit FMU registers */ +#define GIC_FMU_WRITE_64(base, reg, n, val) \ + do { \ + /* \ + * This register receives the unlock key that is required for \ + * writes to FMU registers to be successful. \ + */ \ + mmio_write_32(base + GICFMU_KEY, 0xBE); \ + /* \ + * APB bus is 32-bit wide; so split the 64-bit write into \ + * two 32-bit writes \ + */ \ + mmio_write_32((base) + reg##_LO + (n * 64), (val)); \ + mmio_write_32((base) + reg##_HI + (n * 64), (val)); \ + } while (false) + +/* Helper function to wait until FMU is ready to accept the next command */ +static void wait_until_fmu_is_idle(uintptr_t base) +{ + uint64_t timeout_ref = timeout_init_us(GICFMU_IDLE_TIMEOUT_US); + uint64_t status; + + /* wait until status is 'busy' */ + do { + status = (gic_fmu_read_status(base) & BIT(0)); + + if (timeout_elapsed(timeout_ref)) { + ERROR("GIC600 AE FMU is not responding\n"); + panic(); + } + } while (status == U(0)); +} + +#define GIC_FMU_WRITE_ON_IDLE_32(base, reg, val) \ + do { \ + /* Wait until FMU is ready */ \ + wait_until_fmu_is_idle(base); \ + /* Actual register write */ \ + GIC_FMU_WRITE_32(base, reg, val); \ + /* Wait until FMU is ready */ \ + wait_until_fmu_is_idle(base); \ + } while (false) + +#define GIC_FMU_WRITE_ON_IDLE_64(base, reg, n, val) \ + do { \ + /* Wait until FMU is ready */ \ + wait_until_fmu_is_idle(base); \ + /* Actual register write */ \ + GIC_FMU_WRITE_64(base, reg, n, val); \ + /* Wait until FMU is ready */ \ + wait_until_fmu_is_idle(base); \ + } while (false) + +/******************************************************************************* + * GIC FMU functions for accessing the Fault Management Unit registers + ******************************************************************************/ + +/* + * Accessors to read the Error Record Feature Register bits corresponding + * to an error record 'n' + */ +uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n) +{ + /* + * APB bus is 32-bit wide; so split the 64-bit read into + * two 32-bit reads + */ + uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRFR_LO + n * 64U); + + reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRFR_HI + n * 64U) << 32); + return reg_val; +} + +/* + * Accessors to read the Error Record Control Register bits corresponding + * to an error record 'n' + */ +uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n) +{ + /* + * APB bus is 32-bit wide; so split the 64-bit read into + * two 32-bit reads + */ + uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_LO + n * 64U); + + reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRCTLR_HI + n * 64U) << 32); + return reg_val; +} + +/* + * Accessors to read the Error Record Primary Status Register bits + * corresponding to an error record 'n' + */ +uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n) +{ + /* + * APB bus is 32-bit wide; so split the 64-bit read into + * two 32-bit reads + */ + uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_LO + n * 64U); + + reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRSTATUS_HI + n * 64U) << 32); + return reg_val; +} + +/* + * Accessors to read the Error Group Status Register + */ +uint64_t gic_fmu_read_errgsr(uintptr_t base) +{ + /* + * APB bus is 32-bit wide; so split the 64-bit read into + * two 32-bit reads + */ + uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_ERRGSR_LO); + + reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_ERRGSR_HI) << 32); + return reg_val; +} + +/* + * Accessors to read the Ping Control Register + */ +uint32_t gic_fmu_read_pingctlr(uintptr_t base) +{ + return mmio_read_32(base + GICFMU_PINGCTLR); +} + +/* + * Accessors to read the Ping Now Register + */ +uint32_t gic_fmu_read_pingnow(uintptr_t base) +{ + return mmio_read_32(base + GICFMU_PINGNOW); +} + +/* + * Accessors to read the Ping Mask Register + */ +uint64_t gic_fmu_read_pingmask(uintptr_t base) +{ + /* + * APB bus is 32-bit wide; so split the 64-bit read into + * two 32-bit reads + */ + uint64_t reg_val = (uint64_t)mmio_read_32(base + GICFMU_PINGMASK_LO); + + reg_val |= ((uint64_t)mmio_read_32(base + GICFMU_PINGMASK_HI) << 32); + return reg_val; +} + +/* + * Accessors to read the FMU Status Register + */ +uint32_t gic_fmu_read_status(uintptr_t base) +{ + return mmio_read_32(base + GICFMU_STATUS); +} + +/* + * Accessors to read the Error Record ID Register + */ +uint32_t gic_fmu_read_erridr(uintptr_t base) +{ + return mmio_read_32(base + GICFMU_ERRIDR); +} + +/* + * Accessors to write a 64 bit value to the Error Record Control Register + */ +void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val) +{ + GIC_FMU_WRITE_64(base, GICFMU_ERRCTLR, n, val); +} + +/* + * Accessors to write a 64 bit value to the Error Record Primary Status + * Register + */ +void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val) +{ + /* Wait until FMU is ready before writing */ + GIC_FMU_WRITE_ON_IDLE_64(base, GICFMU_ERRSTATUS, n, val); +} + +/* + * Accessors to write a 32 bit value to the Ping Control Register + */ +void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val) +{ + GIC_FMU_WRITE_32(base, GICFMU_PINGCTLR, val); +} + +/* + * Accessors to write a 32 bit value to the Ping Now Register + */ +void gic_fmu_write_pingnow(uintptr_t base, uint32_t val) +{ + /* Wait until FMU is ready before writing */ + GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_PINGNOW, val); +} + +/* + * Accessors to write a 32 bit value to the Safety Mechanism Enable Register + */ +void gic_fmu_write_smen(uintptr_t base, uint32_t val) +{ + /* Wait until FMU is ready before writing */ + GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMEN, val); +} + +/* + * Accessors to write a 32 bit value to the Safety Mechanism Inject Error + * Register + */ +void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val) +{ + /* Wait until FMU is ready before writing */ + GIC_FMU_WRITE_ON_IDLE_32(base, GICFMU_SMINJERR, val); +} + +/* + * Accessors to write a 64 bit value to the Ping Mask Register + */ +void gic_fmu_write_pingmask(uintptr_t base, uint64_t val) +{ + GIC_FMU_WRITE_64(base, GICFMU_PINGMASK, 0, val); +} diff --git a/drivers/arm/gic/v3/gicv3.mk b/drivers/arm/gic/v3/gicv3.mk index a2fc16f9c..d7e3536db 100644 --- a/drivers/arm/gic/v3/gicv3.mk +++ b/drivers/arm/gic/v3/gicv3.mk @@ -1,11 +1,13 @@ # # Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2021, NVIDIA Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # # Default configuration values GICV3_SUPPORT_GIC600 ?= 0 +GICV3_SUPPORT_GIC600AE_FMU ?= 0 GICV3_IMPL_GIC600_MULTICHIP ?= 0 GICV3_OVERRIDE_DISTIF_PWR_OPS ?= 0 GIC_ENABLE_V4_EXTN ?= 0 @@ -16,6 +18,11 @@ GICV3_SOURCES += drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicdv3_helpers.c \ drivers/arm/gic/v3/gicrv3_helpers.c +ifeq (${GICV3_SUPPORT_GIC600AE_FMU}, 1) +GICV3_SOURCES += drivers/arm/gic/v3/gic600ae_fmu.c \ + drivers/arm/gic/v3/gic600ae_fmu_helpers.c +endif + ifeq (${GICV3_OVERRIDE_DISTIF_PWR_OPS}, 0) GICV3_SOURCES += drivers/arm/gic/v3/arm_gicv3_common.c endif @@ -29,6 +36,10 @@ endif $(eval $(call assert_boolean,GICV3_SUPPORT_GIC600)) $(eval $(call add_define,GICV3_SUPPORT_GIC600)) +# Set GIC-600AE FMU support +$(eval $(call assert_boolean,GICV3_SUPPORT_GIC600AE_FMU)) +$(eval $(call add_define,GICV3_SUPPORT_GIC600AE_FMU)) + # Set GICv4 extension $(eval $(call assert_boolean,GIC_ENABLE_V4_EXTN)) $(eval $(call add_define,GIC_ENABLE_V4_EXTN)) diff --git a/include/drivers/arm/gic600ae_fmu.h b/include/drivers/arm/gic600ae_fmu.h new file mode 100644 index 000000000..691ffc7b7 --- /dev/null +++ b/include/drivers/arm/gic600ae_fmu.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GIC600AE_FMU_H +#define GIC600AE_FMU_H + +/******************************************************************************* + * GIC600-AE FMU register offsets and constants + ******************************************************************************/ +#define GICFMU_ERRFR_LO U(0x000) +#define GICFMU_ERRFR_HI U(0x004) +#define GICFMU_ERRCTLR_LO U(0x008) +#define GICFMU_ERRCTLR_HI U(0x00C) +#define GICFMU_ERRSTATUS_LO U(0x010) +#define GICFMU_ERRSTATUS_HI U(0x014) +#define GICFMU_ERRGSR_LO U(0xE00) +#define GICFMU_ERRGSR_HI U(0xE04) +#define GICFMU_KEY U(0xEA0) +#define GICFMU_PINGCTLR U(0xEA4) +#define GICFMU_PINGNOW U(0xEA8) +#define GICFMU_SMEN U(0xEB0) +#define GICFMU_SMINJERR U(0xEB4) +#define GICFMU_PINGMASK_LO U(0xEC0) +#define GICFMU_PINGMASK_HI U(0xEC4) +#define GICFMU_STATUS U(0xF00) +#define GICFMU_ERRIDR U(0xFC8) + +/* ERRCTLR bits */ +#define FMU_ERRCTLR_ED_BIT BIT(0) +#define FMU_ERRCTLR_CE_EN_BIT BIT(1) +#define FMU_ERRCTLR_UI_BIT BIT(2) +#define FMU_ERRCTLR_CI_BIT BIT(3) + +/* SMEN constants */ +#define FMU_SMEN_BLK_SHIFT U(8) +#define FMU_SMEN_SMID_SHIFT U(24) + +/* Error record IDs */ +#define FMU_BLK_GICD U(0) +#define FMU_BLK_SPICOL U(1) +#define FMU_BLK_WAKERQ U(2) +#define FMU_BLK_ITS0 U(4) +#define FMU_BLK_ITS1 U(5) +#define FMU_BLK_ITS2 U(6) +#define FMU_BLK_ITS3 U(7) +#define FMU_BLK_ITS4 U(8) +#define FMU_BLK_ITS5 U(9) +#define FMU_BLK_ITS6 U(10) +#define FMU_BLK_ITS7 U(11) +#define FMU_BLK_PPI0 U(12) +#define FMU_BLK_PPI1 U(13) +#define FMU_BLK_PPI2 U(14) +#define FMU_BLK_PPI3 U(15) +#define FMU_BLK_PPI4 U(16) +#define FMU_BLK_PPI5 U(17) +#define FMU_BLK_PPI6 U(18) +#define FMU_BLK_PPI7 U(19) +#define FMU_BLK_PPI8 U(20) +#define FMU_BLK_PPI9 U(21) +#define FMU_BLK_PPI10 U(22) +#define FMU_BLK_PPI11 U(23) +#define FMU_BLK_PPI12 U(24) +#define FMU_BLK_PPI13 U(25) +#define FMU_BLK_PPI14 U(26) +#define FMU_BLK_PPI15 U(27) +#define FMU_BLK_PPI16 U(28) +#define FMU_BLK_PPI17 U(29) +#define FMU_BLK_PPI18 U(30) +#define FMU_BLK_PPI19 U(31) +#define FMU_BLK_PPI20 U(32) +#define FMU_BLK_PPI21 U(33) +#define FMU_BLK_PPI22 U(34) +#define FMU_BLK_PPI23 U(35) +#define FMU_BLK_PPI24 U(36) +#define FMU_BLK_PPI25 U(37) +#define FMU_BLK_PPI26 U(38) +#define FMU_BLK_PPI27 U(39) +#define FMU_BLK_PPI28 U(40) +#define FMU_BLK_PPI29 U(41) +#define FMU_BLK_PPI30 U(42) +#define FMU_BLK_PPI31 U(43) +#define FMU_BLK_PRESENT_MASK U(0xFFFFFFFFFFF) + +/* Safety Mechamism limit */ +#define FMU_SMID_GICD_MAX U(33) +#define FMU_SMID_SPICOL_MAX U(5) +#define FMU_SMID_WAKERQ_MAX U(2) +#define FMU_SMID_ITS_MAX U(14) +#define FMU_SMID_PPI_MAX U(12) + +/* MBIST Safety Mechanism ID */ +#define GICD_MBIST_REQ_ERROR U(23) +#define GICD_FMU_CLKGATE_ERROR U(33) +#define PPI_MBIST_REQ_ERROR U(10) +#define PPI_FMU_CLKGATE_ERROR U(12) +#define ITS_MBIST_REQ_ERROR U(13) +#define ITS_FMU_CLKGATE_ERROR U(14) + +/* ERRSTATUS bits */ +#define FMU_ERRSTATUS_V_BIT BIT(30) +#define FMU_ERRSTATUS_UE_BIT BIT(29) +#define FMU_ERRSTATUS_OV_BIT BIT(27) +#define FMU_ERRSTATUS_CE_BITS (BIT(25) | BIT(24)) +#define FMU_ERRSTATUS_CLEAR (FMU_ERRSTATUS_V_BIT | FMU_ERRSTATUS_UE_BIT | \ + FMU_ERRSTATUS_OV_BIT | FMU_ERRSTATUS_CE_BITS) + +/* PINGCTLR constants */ +#define FMU_PINGCTLR_INTDIFF_SHIFT U(16) +#define FMU_PINGCTLR_TIMEOUTVAL_SHIFT U(4) +#define FMU_PINGCTLR_EN_BIT BIT(0) + +#ifndef __ASSEMBLER__ + +#include + +#include + +/******************************************************************************* + * GIC600 FMU EL3 driver API + ******************************************************************************/ +uint64_t gic_fmu_read_errfr(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errctlr(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errstatus(uintptr_t base, unsigned int n); +uint64_t gic_fmu_read_errgsr(uintptr_t base); +uint32_t gic_fmu_read_pingctlr(uintptr_t base); +uint32_t gic_fmu_read_pingnow(uintptr_t base); +uint64_t gic_fmu_read_pingmask(uintptr_t base); +uint32_t gic_fmu_read_status(uintptr_t base); +uint32_t gic_fmu_read_erridr(uintptr_t base); +void gic_fmu_write_errctlr(uintptr_t base, unsigned int n, uint64_t val); +void gic_fmu_write_errstatus(uintptr_t base, unsigned int n, uint64_t val); +void gic_fmu_write_pingctlr(uintptr_t base, uint32_t val); +void gic_fmu_write_pingnow(uintptr_t base, uint32_t val); +void gic_fmu_write_smen(uintptr_t base, uint32_t val); +void gic_fmu_write_sminjerr(uintptr_t base, uint32_t val); +void gic_fmu_write_pingmask(uintptr_t base, uint64_t val); + +void gic600_fmu_init(uint64_t base, uint64_t blk_present_mask, bool errctlr_ce_en, bool errctlr_ue_en); +void gic600_fmu_enable_ping(uint64_t base, uint64_t blk_present_mask, + unsigned int timeout_val, unsigned int interval_diff); +void gic600_fmu_print_sm_info(uint64_t base, unsigned int blk, unsigned int smid); + +#endif /* __ASSEMBLER__ */ + +#endif /* GIC600AE_FMU_H */ -- cgit v1.2.3 From 7c78e4f7df43f09e54c26637711c6341761f3314 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Thu, 25 Mar 2021 14:56:16 +0530 Subject: docs: nxp soc-lx2160a based platforms Addition of documents for platforms based on NXP SoC LX2160A. Signed-off-by: Pankaj Gupta Change-Id: I39ac5a9eb0b668d26301a0a24a1e6bf87f245f02 --- docs/plat/index.rst | 1 + docs/plat/nxp/index.rst | 17 +++ docs/plat/nxp/nxp-layerscape.rst | 232 +++++++++++++++++++++++++++++++ docs/plat/nxp/nxp-ls-fuse-prov.rst | 271 +++++++++++++++++++++++++++++++++++++ docs/plat/nxp/nxp-ls-tbbr.rst | 210 ++++++++++++++++++++++++++++ 5 files changed, 731 insertions(+) create mode 100644 docs/plat/nxp/index.rst create mode 100644 docs/plat/nxp/nxp-layerscape.rst create mode 100644 docs/plat/nxp/nxp-ls-fuse-prov.rst create mode 100644 docs/plat/nxp/nxp-ls-tbbr.rst diff --git a/docs/plat/index.rst b/docs/plat/index.rst index 4dc9ecd23..5848005ba 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -27,6 +27,7 @@ Platform Ports imx8 imx8m ls1043a + nxp/index poplar qemu qemu-sbsa diff --git a/docs/plat/nxp/index.rst b/docs/plat/nxp/index.rst new file mode 100644 index 000000000..85468877b --- /dev/null +++ b/docs/plat/nxp/index.rst @@ -0,0 +1,17 @@ +NXP Reference Development Platforms +=================================== + +.. toctree:: + :maxdepth: 1 + :caption: Contents + + nxp-layerscape + nxp-ls-fuse-prov + nxp-ls-tbbr + +This chapter holds documentation related to NXP reference development platforms. +It includes details on image flashing, fuse provisioning and trusted board boot-up. + +-------------- + +*Copyright (c) 2021, NXP Limited. All rights reserved.* diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst new file mode 100644 index 000000000..3d983542f --- /dev/null +++ b/docs/plat/nxp/nxp-layerscape.rst @@ -0,0 +1,232 @@ +NXP SoCs - Overview +===================== +.. section-numbering:: + :suffix: . + +The QorIQ family of ARM based SoCs that are supported on TF-A are: + +1. LX2160ARDB: + Platform Name: + + a. lx2160ardb (Board details can be fetched from the link: `lx2160ardb`_) + + +Table of supported boot-modes by each platform & platform that needs FIP-DDR: +----------------------------------------------------------------------------- + ++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ +| | BOOT_MODE-->| sd | qspi | nor | nand | emmc | flexspi_nor | flexspi_nand | fip_ddr needed | +| | | | | | | | | | | +| | PLAT | | | | | | | | | ++===+=================+=======+========+=======+=======+=======+=============+==============+=================+ +| 1.| lx2160ardb | yes | | | | yes | yes | | yes | ++---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ + +Boot Sequence +------------- +:: + ++ Secure World | Normal World ++ EL0 | ++ | ++ EL1 BL32(Tee OS) | kernel ++ ^ | | ^ ++ | | | | ++ EL2 | | | BL33(u-boot) ++ | | | ^ ++ | v | / ++ EL3 BootROM --> BL2 --> BL31 ---------------/ ++ + +Boot Sequence with FIP-DDR +-------------------------- +:: + ++ Secure World | Normal World ++ EL0 | ++ | ++ EL1 fip-ddr BL32(Tee OS) | kernel ++ ^ | ^ | | ^ ++ | | | | | | ++ EL2 | | | | | BL33(u-boot) ++ | | | | | ^ ++ | v | v | / ++ EL3 BootROM --> BL2 -----> BL31 ---------------/ ++ + + +How to build +============= + +Code Locations +-------------- + +- OP-TEE: + `link `__ + +- U-Boot: + `link `__ + +- RCW: + `link `__ + +- ddr-phy-binary: Required by platforms that need fip-ddr. + `link `__ + +- cst: Required for TBBR. + `link `__ + +Build Procedure +--------------- + +- Fetch all the above repositories into local host. + +- Prepare AARCH64 toolchain and set the environment variable "CROSS_COMPILE". + + .. code:: shell + + export CROSS_COMPILE=.../bin/aarch64-linux-gnu- + +- Build RCW. Refer README from the respective cloned folder for more details. + +- Build u-boot and OPTee firstly, and get binary images: u-boot.bin and tee.bin. + For u-boot you can use the _tfa_defconfig for build. + +- Copy/clone the repo "ddr-phy-binary" to the tfa directory for platform needing ddr-fip. + +- Below are the steps to build TF-A images for the supported platforms. + +Compilation steps without BL32 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +BUILD BL2: + +-To compile + .. code:: shell + + make PLAT=$PLAT \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + pbl + +BUILD FIP: + + .. code:: shell + + make PLAT=$PLAT \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL33=$UBOOT_SECURE_BIN \ + pbl \ + fip + +Compilation steps with BL32 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +BUILD BL2: + +-To compile + .. code:: shell + + make PLAT=$PLAT \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + pbl + +BUILD FIP: + + .. code:: shell + + make PLAT=$PLAT \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + BL33=$UBOOT_SECURE_BIN \ + pbl \ + fip + + +BUILD fip-ddr (Mandatory for certain platforms, refer table above): +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-To compile additional fip-ddr for selected platforms(Refer above table if the platform needs fip-ddr). + .. code:: shell + + make PLAT= fip-ddr + + +Deploy ATF Images +================= + +Note: The size in the standard uboot commands for copy to nor, qspi, nand or sd +should be modified based on the binary size of the image to be copied. + +- Deploy ATF images on flexspi-Nor flash Alt Bank from U-Boot prompt. + -- Commands to flash images for bl2_xxx.pbl and fip.bin. + + .. code:: shell + + tftp 82000000 $path/bl2_flexspi_nor.pbl; + i2c mw 66 50 20;sf probe 0:0; sf erase 0 +$filesize; sf write 0x82000000 0x0 $filesize; + + tftp 82000000 $path/fip.bin; + i2c mw 66 50 20;sf probe 0:0; sf erase 0x100000 +$filesize; sf write 0x82000000 0x100000 $filesize; + + -- Next step is valid for platform where FIP-DDR is needed. + + .. code:: shell + + tftp 82000000 $path/ddr_fip.bin; + i2c mw 66 50 20;sf probe 0:0; sf erase 0x800000 +$filesize; sf write 0x82000000 0x800000 $filesize; + + -- Then reset to alternate bank to boot up ATF. + + .. code:: shell + + qixisreset altbank; + +- Deploy ATF images on SD/eMMC from U-Boot prompt. + -- file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512) + + .. code:: shell + + mmc dev ; (idx = 1 for eMMC; idx = 0 for SD) + + tftp 82000000 $path/bl2__or_.pbl; + mmc write 82000000 8 ; + + tftp 82000000 $path/fip.bin; + mmc write 82000000 0x800 ; + + -- Next step is valid for platform that needs FIP-DDR. + + .. code:: shell + + tftp 82000000 $path/ddr_fip.bin; + mmc write 82000000 0x4000 ; + + -- Then reset to sd/emmc to boot up ATF from sd/emmc as boot-source. + + .. code:: shell + + qixisreset ; + +Trusted Board Boot: +=================== + +For TBBR, the binary name changes: + ++-------------+--------------------------+---------+-------------------+ +| Boot Type | BL2 | FIP | FIP-DDR | ++=============+==========================+=========+===================+ +| Normal Boot | bl2_.pbl | fip.bin | ddr_fip.bin | ++-------------+--------------------------+---------+-------------------+ +| TBBR Boot | bl2__sec.pbl | fip.bin | ddr_fip_sec.bin | ++-------------+--------------------------+---------+-------------------+ + +Refer `nxp-ls-tbbr.rst`_ for detailed user steps. + + +.. _lx2160ardb: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-communication-process/layerscape-lx2160a-multicore-communications-processor:LX2160A +.. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst diff --git a/docs/plat/nxp/nxp-ls-fuse-prov.rst b/docs/plat/nxp/nxp-ls-fuse-prov.rst new file mode 100644 index 000000000..64e1c6f8c --- /dev/null +++ b/docs/plat/nxp/nxp-ls-fuse-prov.rst @@ -0,0 +1,271 @@ + +Steps to blow fuses on NXP LS SoC: +================================== + + +- Enable POVDD + -- Refer board GSG(Getting Started Guide) for the steps to enable POVDD. + -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk. + ++---+-----------------+-----------+------------+-----------------+-----------------------------+ +| | Platform | Jumper | Switch | LED to Verify | Through GPIO Pin (=number) | ++===+=================+===========+============+=================+=============================+ +| 1.| lx2160ardb | J9 | | | no | ++---+-----------------+-----------+------------+-----------------+-----------------------------+ +| 2.| lx2160aqds | J35 | | | no | ++---+-----------------+-----------+------------+-----------------+-----------------------------+ +| 3.| lx2162aqds | J35 | SW9[4] = 1 | D15 | no | ++---+-----------------+-----------+------------+-----------------+-----------------------------+ + +- SFP registers to be written to: + ++---+----------------------------------+----------------------+----------------------+ +| | Platform | OTPMKR0..OTPMKR7 | SRKHR0..SRKHR7 | ++===+==================================+======================+======================+ +| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x1e80234..0x1e80250 | 0x1e80254..0x1e80270 | ++---+----------------------------------+----------------------+----------------------+ + +- At U-Boot prompt, verify that SNVS register - HPSR, whether OTPMK was written, already: + ++---+----------------------------------+-------------------------------------------+---------------+ +| | Platform | OTPMK_ZERO_BIT(=value) | SNVS_HPSR_REG | ++===+==================================+===========================================+===============+ +| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 27 (= 1 means not blown, =0 means blown) | 0x01E90014 | ++---+----------------------------------+-------------------------------------------+---------------+ + +From u-boot prompt: + + -- Check for the OTPMK. + .. code:: shell + + md $SNVS_HPSR_REG + + Command Output: + 01e90014: 88000900 + + In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap). + +0 +4 +8 +C + [0x01E90014] 88000900 + + Note: OTPMK_ZERO_BIT is 1, indicating that the OTPMK is not blown. + + -- Check for the SRK Hash. + .. code:: shell + + md $SRKHR0 0x10 + + Command Output: + 01e80254: 00000000 00000000 00000000 00000000 ................ + 01e80264: 00000000 00000000 00000000 00000000 ................ + + Note: Zero means that SRK hash is not blown. + +- If not blown, then from the U-Boot prompt, using following commands: + -- Provision the OTPMK. + + .. code:: shell + + mw.l $OTPMKR0 + mw.l $OTPMKR1 + mw.l $OTPMKR2 + mw.l $OTPMKR3 + mw.l $OTPMKR4 + mw.l $OTPMKR5 + mw.l $OTPMKR6 + mw.l $OTPMKR7 + + -- Provision the SRK Hash. + + .. code:: shell + + mw.l $SRKHR0 + mw.l $SRKHR1 + mw.l $SRKHR2 + mw.l $SRKHR3 + mw.l $SRKHR4 + mw.l $SRKHR5 + mw.l $SRKHR6 + mw.l $SRKHR7 + + Note: SRK Hash should be carefully written keeping in mind the SFP Block Endianness. + +- At U-Boot prompt, verify that SNVS registers for OTPMK are correctly written: + + -- Check for the OTPMK. + .. code:: shell + + md $SNVS_HPSR_REG + + Command Output: + 01e90014: 80000900 + + OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown. + + Note: In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap). + + .. code:: shell + + md $OTPMKR0 0x10 + + Command Output: + 01e80234: ffffffff ffffffff ffffffff ffffffff ................ + 01e80244: ffffffff ffffffff ffffffff ffffffff ................ + + Note: OTPMK will never be visible in plain. + + -- Check for the SRK Hash. For example, if following SRK hash is written: + + SFP SRKHR0 = fdc2fed4 + SFP SRKHR1 = 317f569e + SFP SRKHR2 = 1828425c + SFP SRKHR3 = e87b5cfd + SFP SRKHR4 = 34beab8f + SFP SRKHR5 = df792a70 + SFP SRKHR6 = 2dff85e1 + SFP SRKHR7 = 32a29687, + + then following would be the value on dumping SRK hash. + + .. code:: shell + + md $SRKHR0 0x10 + + Command Output: + 01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8 ....1.V..(B\.{\. + 01e80264: 8fabbe34 702a79df e185ff2d 8796a232 4....y*p-...2... + + Note: SRK Hash is visible in plain based on the SFP Block Endianness. + +- Caution: Donot proceed to the next step, until you are sure that OTPMK and SRKH are correctly blown from above steps. + -- After the next step, there is no turning back. + -- Fuses will be burnt, which cannot be undo. + +- Write SFP_INGR[INST] with the PROGFB(0x2) instruction to blow the fuses. + -- User need to save the SRK key pair and OTPMK Key forever, to continue using this board. + ++---+----------------------------------+-------------------------------------------+-----------+ +| | Platform | SFP_INGR_REG | SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE | ++===+==================================+=======================================================+ +| 1.| lx2160ardb/lx2160aqds/lx2162aqds | 0x01E80020 | 0x2 | ++---+----------------------------------+--------------+----------------------------------------+ + + .. code:: shell + + md $SFP_INGR_REG $SFP_WRITE_DATE_FRM_MIRROR_REG_TO_FUSE + +- On reset, if the SFP register were read from u-boot, it will show the following: + -- Check for the OTPMK. + + .. code:: shell + + md $SNVS_HPSR_REG + + Command Output: + 01e90014: 80000900 + + In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap). + +0 +4 +8 +C + [0x01E90014] 80000900 + + Note: OTPMK_ZERO_BIT is zero, indicating that the OTPMK is blown. + + .. code:: shell + + md $OTPMKR0 0x10 + + Command Output: + 01e80234: ffffffff ffffffff ffffffff ffffffff ................ + 01e80244: ffffffff ffffffff ffffffff ffffffff ................ + + Note: OTPMK will never be visible in plain. + + -- SRK Hash + + .. code:: shell + + md $SRKHR0 0x10 + + Command Output: + 01e80254: d4fec2fd 9e567f31 5c422818 fd5c7be8 ....1.V..(B\.{\. + 01e80264: 8fabbe34 702a79df e185ff2d 8796a232 4....y*p-...2... + + Note: SRK Hash is visible in plain based on the SFP Block Endianness. + +Second method to do the fuse provsioning: +========================================= + +This method is used for quick way to provision fuses. +Typically used by those who needs to provision number of boards. + +- Enable POVDD: + -- Refer the table above to enable POVDD. + + Note: If GPIO Pin supports enabling POVDD, it can be done through the below input_fuse_file. + + -- Once the POVDD is enabled, make sure to set variable POVDD_ENABLE := yes, in the platform.mk. + +- User need to populate the "input_fuse_file", corresponding to the platform for: + + -- OTPMK + -- SRKH + + Table of fuse provisioning input file for every supported platform: + ++---+----------------------------------+-----------------------------------------------------------------+ +| | Platform | FUSE_PROV_FILE | ++===+==================================+=================================================================+ +| 1.| lx2160ardb/lx2160aqds/lx2162aqds | ${CST_DIR}/input_files/gen_fusescr/ls2088_1088/input_fuse_file | ++---+----------------------------------+--------------+--------------------------------------------------+ + +- Create the TF-A binary with FUSE_PROG=1. + + .. code:: shell + + make PLAT=$PLAT FUSE_PROG=1\ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + BL33=$UBOOT_SECURE_BIN \ + pbl \ + fip \ + fip_fuse \ + FUSE_PROV_FILE=../../apps/security/cst/input_files/gen_fusescr/ls2088_1088/input_fuse_file + +- Deployment: + -- Refer the nxp-layerscape.rst for deploying TF-A images. + -- Deploying fip_fuse.bin: + + For Flexspi-Nor: + + .. code:: shell + + tftp 82000000 $path/fuse_fip.bin; + i2c mw 66 50 20;sf probe 0:0; sf erase 0x880000 +$filesize; sf write 0x82000000 0x880000 $filesize; + + For SD or eMMC [file_size_in_block_sizeof_512 = (Size_of_bytes_tftp / 512)]: + + .. code:: shell + + tftp 82000000 $path/fuse_fip.bin; + mmc write 82000000 0x4408 ; + +- Valiation: + ++---+----------------------------------+---------------------------------------------------+ +| | Platform | Error_Register | Error_Register_Address | ++===+==================================+===================================================+ +| 1.| lx2160ardb/lx2160aqds/lx2162aqds | DCFG scratch 4 register | 0x01EE020C | ++---+----------------------------------+---------------------------------------------------+ + + At the U-Boot prompt, check DCFG scratch 4 register for any error. + + .. code:: shell + + md $Error_Register_Address 1 + + Command Ouput: + 01ee020c: 00000000 + + Note: + - 0x00000000 shows no error, then fuse provisioning is successful. + - For non-zero value, refer the code header file ".../drivers/nxp/sfp/sfp_error_codes.h" diff --git a/docs/plat/nxp/nxp-ls-tbbr.rst b/docs/plat/nxp/nxp-ls-tbbr.rst new file mode 100644 index 000000000..43e15f7ef --- /dev/null +++ b/docs/plat/nxp/nxp-ls-tbbr.rst @@ -0,0 +1,210 @@ + +-------------- +NXP Platforms: +-------------- +TRUSTED_BOARD_BOOT option can be enabled by specifying TRUSTED_BOARD_BOOT=1 on command line during make. + + + +Bare-Minimum Preparation to run TBBR on NXP Platforms: +======================================================= +- OTPMK(One Time Programable Key) needs to be burnt in fuses. + -- It is the 256 bit key that stores a secret value used by the NXP SEC 4.0 IP in Trusted or Secure mode. + + Note: It is primarily for the purpose of decrypting additional secrets stored in system non-volatile memory. + + -- NXP CST tool gives an option to generate it. + + Use the below command from directory 'cst', with correct options. + + .. code:: shell + + ./gen_otpmk_drbg + +- SRKH (Super Root Key Hash) needs to be burnt in fuses. + -- It is the 256 bit hash of the list of the public keys of the SRK key pair. + -- NXP CST tool gives an option to generate the RSA key pair and its hash. + + Use the below command from directory 'cst', with correct options. + + .. code:: shell + + ./gen_keys + +Refer fuse frovisioning readme 'nxp-ls-fuse-prov.rst' for steps to blow these keys. + + + +Two options are provided for TRUSTED_BOARD_BOOT: +================================================ + +------------------------------------------------------------------------- +Option 1: CoT using X 509 certificates +------------------------------------------------------------------------- + +- This CoT is as provided by ARM. + +- To use this option user needs to specify mbedtld dir path in MBEDTLS_DIR. + +- To generate CSF header, path of CST repository needs to be specified as CST_DIR + +- CSF header is embedded to each of the BL2 image. + +- GENERATE_COT=1 adds the tool 'cert_create' to the build environment to generate: + -- X509 Certificates as (.crt) files. + -- X509 Pem key file as (.pem) files. + +- SAVE_KEYS=1 saves the keys and certificates, if GENERATE_COT=1. + -- For this to work, file name for cert and keys are provided as part of compilation or build command. + + --- default file names will be used, incase not provided as part compilation or build command. + --- default folder 'BUILD_PLAT' will be used to store them. + +- ROTPK for x.509 certificates is generated and embedded in bl2.bin and + verified as part of CoT by Boot ROM during secure boot. + +- Compilation steps: + +All Images + .. code:: shell + + make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH CST_DIR=$CST_DIR_PATH \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + BL33=$UBOOT_SECURE_BIN \ + pbl \ + fip + +Additional FIP_DDR Image (For NXP platforms like lx2160a) + .. code:: shell + + make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 MBEDTLS_DIR=$MBEDTLS_PATH fip_ddr + + Note: make target 'fip_ddr' should never be combine with other make target 'fip', 'pbl' & 'bl2'. + +------------------------------------------------------------------------- +Option 2: CoT using NXP CSF headers. +------------------------------------------------------------------------- + +- This option is automatically selected when TRUSTED_BOARD_BOOT is set but MBEDTLS_DIR path is not specified. + +- CSF header is embedded to each of the BL31, BL32 and BL33 image. + +- To generate CSF header, path of CST repository needs to be specified as CST_DIR + +- Default input files for CSF header generation is added in this repo. + +- Default input file requires user to generate RSA key pair named + -- srk.pri, and + -- srk.pub, and add them in ATF repo. + -- These keys can be generated using gen_keys tool of CST. + +- To change the input file , user can use the options BL33_INPUT_FILE, BL32_INPUT_FILE, BL31_INPUT_FILE + +- There are 2 paths in secure boot flow : + -- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0) + + --- In this flow , even on ROTPK comparison failure, flow would continue. + --- However SNVS is transitioned to non-secure state + + -- Production mode (SFP->OSPR, ITS = 1) + + --- Any failure is fatal failure + +- Compilation steps: + +All Images + .. code:: shell + + make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + BL33=$UBOOT_SECURE_BIN \ + pbl \ + fip + +Additional FIP_DDR Image (For NXP platforms like lx2160a) + .. code:: shell + + make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH fip_ddr + +- Compilation Steps with build option for generic image processing filters to prepend CSF header: + -- Generic image processing filters to prepend CSF header + + BL32_INPUT_FILE = < file name> + BL33_INPUT_FILE = + + .. code:: shell + + make PLAT=$PLAT TRUSTED_BOARD_BOOT=1 CST_DIR=$CST_DIR_PATH \ + BOOT_MODE= \ + RCW=$RCW_BIN \ + BL32=$TEE_BIN SPD=opteed\ + BL33=$UBOOT_SECURE_BIN \ + BL33_INPUT_FILE = \ + BL32_INPUT_FILE = \ + BL31_INPUT_FILE = \ + pbl \ + fip + + +Deploy ATF Images +================= +Same steps as mentioned in the readme "nxp-layerscape.rst". + + + +Verification to check if Secure state is achieved: +================================================== + ++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+ +| | Platform | SNVS_HPSR_REG | SYS_SECURE_BIT(=value) | SYSTEM_SECURE_CONFIG_BIT(=value) | SSM_STATE | ++===+================+=================+========================+==================================+===============================+ +| 1.| lx2160ardb or | 0x01E90014 | 15 | 14-12 | 11-8 | +| | lx2160aqds or | | ( = 1, BootROM Booted) | ( = 010 means Intent to Secure, | (=1111 means secure boot) | +| | lx2162aqds | | | ( = 000 Unsecure) | (=1011 means Non-secure Boot) | ++---+----------------+-----------------+------------------------+----------------------------------+-------------------------------+ + +- Production mode (SFP->OSPR, ITS = 1) + -- Linux prompt will successfully come. if the TBBR is successful. + + --- Else, Linux boot will be successful. + + -- For secure-boot status, read SNVS Register $SNVS_HPSR_REG from u-boot prompt: + + .. code:: shell + + md $SNVS_HPSR_REG + + Command Output: + 1e90014: 8000AF00 + + In case it is read as 00000000, then read this register using jtag (in development mode only through CW tap). + +0 +4 +8 +C + [0x01E90014] 8000AF00 + + +- Development Mode (sb_en in RCW = 1, SFP->OSPR, ITS = 0) + -- Refer the SoC specific table to read the register to interpret whether the secure boot is achieved or not. + -- Using JTAG (in development environment only, using CW tap): + + --- For secure-boot status, read SNVS Register $SNVS_HPSR_REG + + .. code:: shell + + ccs::display_regs 86 0x01E90014 4 0 1 + + Command Output: + Using the SAP chain position number 86, following is the output. + + +0 +4 +8 +C + [0x01E90014] 8000AF00 + + Note: Chain position number will vary from one SoC to other SoC. + +- Interpretation of the value: + + -- 0xA indicates BootROM booted, with intent to secure. + -- 0xF = secure boot, as SSM_STATE. -- cgit v1.2.3 From 33993a3737737a03ee5a9d386d0a027bdc947c9c Mon Sep 17 00:00:00 2001 From: Balint Dobszay Date: Fri, 26 Mar 2021 15:19:11 +0100 Subject: feat(fvp): enable external SP images in BL2 config Currently the list of SP UUIDs loaded by BL2 is hardcoded in the DT. This is a problem when building a system with other SPs (e.g. from Trusted Services). This commit implements a workaround to enable adding SP UUIDs to the list at build time. Signed-off-by: Balint Dobszay Change-Id: Iff85d3778596d23d777dec458f131bd7a8647031 --- Makefile | 4 ++++ docs/plat/arm/arm-build-options.rst | 3 +++ plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/Makefile b/Makefile index b4bebf17f..841135554 100644 --- a/Makefile +++ b/Makefile @@ -525,6 +525,10 @@ ifneq (${SPD},none) ifeq ($(TS_SP_FW_CONFIG),1) DTC_CPPFLAGS += -DTS_SP_FW_CONFIG endif + + ifneq ($(ARM_BL2_SP_LIST_DTS),) + DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS) + endif else # All other SPDs in spd directory SPD_DIR := spd diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index d4fa98dc5..74251bd28 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -100,6 +100,9 @@ Arm Platform Build Options - ``ARM_SPMC_MANIFEST_DTS`` : path to an alternate manifest file used as the SPMC Core manifest. Valid when ``SPD=spmd`` is selected. +- ``ARM_BL2_SP_LIST_DTS``: Path to DTS file snippet to override the hardcoded + SP nodes in tb_fw_config. + - ``OPTEE_SP_FW_CONFIG``: DTC build flag to include OP-TEE as SP in tb_fw_config device tree. This flag is defined only when ``ARM_SPMC_MANIFEST_DTS`` manifest file name contains pattern optee_sp. diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index 62ab27c9d..08d3c32ea 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + /dts-v1/; / { @@ -74,6 +76,10 @@ secure-partitions { compatible = "arm,sp"; + +#ifdef ARM_BL2_SP_LIST_DTS + #include __XSTRING(ARM_BL2_SP_LIST_DTS) +#else #ifdef OPTEE_SP_FW_CONFIG op-tee { uuid = "486178e0-e7f8-11e3-bc5e-0002a5d5c51b"; @@ -104,6 +110,7 @@ owner = "Plat"; }; #endif +#endif /* ARM_BL2_SP_LIST_DTS */ }; #if COT_DESC_IN_DTB -- cgit v1.2.3 From d4572303ed45faceffed859955b0e71724fddfd2 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 2 Sep 2021 17:02:24 +0100 Subject: fix(arm_fpga): limit BL31 memory usage At the moment we specified the BL31 memory limits to 1MB; since we typically have gigabytes of DRAM, we can be quite generous. However the default parameters expect the devicetree binary at 0x80070000, so we should actually make sure we have no code or data beyond that point. Limit the ARM FPGA BL31 memory footprint to this available 7*64K region. We stay within the limit at the moment, with more than half of it reserved for stacks, so this could be downsized later should we run into problems. The PIE addresses stay as they are, since the default addresses do not apply there anywhere, and the build is broken anyway. Change-Id: I7768af1a93ff67096f4359fc5f5feb66464bafaa Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/include/platform_def.h b/plat/arm/board/arm_fpga/include/platform_def.h index 411b936da..2350d8767 100644 --- a/plat/arm/board/arm_fpga/include/platform_def.h +++ b/plat/arm/board/arm_fpga/include/platform_def.h @@ -30,7 +30,7 @@ #if !ENABLE_PIE #define BL31_BASE UL(0x80000000) -#define BL31_LIMIT UL(0x80100000) +#define BL31_LIMIT UL(0x80070000) #else #define BL31_BASE UL(0x0) #define BL31_LIMIT UL(0x01000000) -- cgit v1.2.3 From 13e16fee86451e2f871c2aac757b32299fe5ead6 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 2 Sep 2021 17:01:53 +0100 Subject: fix(arm_fpga): reserve BL31 memory Embarrassingly we never told the non-secure world that secure firmware lives in the first few hundred KBs of DRAM, so any non-secure payload could happily overwrite TF-A, and we couldn't even blame it. Advertise the BL31 region in the reserved-memory DT node, so non-secure world stays out of it. This fixes Linux booting on FPGAs with less memory than usual. Change-Id: I7fbe7d42c0b251c0ccc43d7c50ca902013d152ec Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index a5f5ea0f3..4a529c6e4 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -144,6 +144,12 @@ static void fpga_prepare_dtb(void) panic(); } + /* Reserve memory used by Trusted Firmware. */ + if (fdt_add_reserved_memory(fdt, "tf-a@80000000", BL31_BASE, + BL31_LIMIT - BL31_BASE)) { + WARN("Failed to add reserved memory node to DT\n"); + } + /* Check for the command line signature. */ if (!strncmp(cmdline, "CMD:", 4)) { int chosen; -- cgit v1.2.3 From b84a850864c05fef587fcbb301f955428966de64 Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Mon, 15 Apr 2019 18:01:29 +0200 Subject: feat(lib/optee): introduce optee_header_is_valid() This new function optee_header_is_valid() allows platform to know whether OP-TEE OS is loaded from multi-image (using OP-TEE header image as BL32_IMAGE_ID) or from a single OP-TEE binary image. The function tee_validate_header() is reworked to return a boolean, and is now silent. Change-Id: Idc7dde091f2ada8898f40d02e68c3834ca39d8e8 Signed-off-by: Etienne Carriere Signed-off-by: Yann Gautier --- include/lib/optee_utils.h | 6 +++++- lib/optee/optee_utils.c | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/lib/optee_utils.h b/include/lib/optee_utils.h index 6067caff4..06378ebbd 100644 --- a/include/lib/optee_utils.h +++ b/include/lib/optee_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,8 +7,12 @@ #ifndef OPTEE_UTILS_H #define OPTEE_UTILS_H +#include + #include +bool optee_header_is_valid(uintptr_t header_base); + int parse_optee_header(entry_point_info_t *header_ep, image_info_t *pager_image_info, image_info_t *paged_image_info); diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c index 0ad108242..d090b3826 100644 --- a/lib/optee/optee_utils.c +++ b/lib/optee/optee_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -47,25 +47,24 @@ typedef struct optee_header { /******************************************************************************* * Check if it is a valid tee header - * Return 1 if valid - * Return 0 if invalid + * Return true if valid + * Return false if invalid ******************************************************************************/ -static inline int tee_validate_header(optee_header_t *header) +static bool tee_validate_header(optee_header_t *header) { - int valid = 0; - if ((header->magic == TEE_MAGIC_NUM_OPTEE) && (header->version == 2u) && (header->nb_images > 0u) && (header->nb_images <= OPTEE_MAX_NUM_IMAGES)) { - valid = 1; + return true; } - else { - WARN("Not a known TEE, use default loading options.\n"); - } + return false; +} - return valid; +bool optee_header_is_valid(uintptr_t header_base) +{ + return tee_validate_header((optee_header_t *)header_base); } /******************************************************************************* -- cgit v1.2.3 From 84090d2ca4aeace94911442ebe4cc7de3ab794e6 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Jul 2021 14:44:09 +0200 Subject: refactor(plat/st): updates for OP-TEE Protect BL32 (SP_min) with MMU if OP-TEE is not used. Validate OP-TEE header with optee_header_is_valid(). Use default values in bl2_mem_params_descs[]. They will be overwritten in bl2_plat_handle_post_image_load() if OP-TEE is used. Change-Id: I8614f3a17caa827561614d0f25f30ee90c4ec3fe Signed-off-by: Etienne Carriere Signed-off-by: Yann Gautier --- plat/st/stm32mp1/bl2_plat_setup.c | 64 +++++++++++++++-------------- plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 13 +++--- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index b4c42fc06..ac2a1e282 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -177,6 +177,11 @@ void bl2_el3_plat_arch_setup(void) mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, STM32MP_OPTEE_SIZE, MT_MEMORY | MT_RW | MT_SECURE); +#else + /* Prevent corruption of preloaded BL32 */ + mmap_add_region(BL32_BASE, BL32_BASE, + BL32_LIMIT - BL32_BASE, + MT_RO_DATA | MT_SECURE); #endif /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, @@ -336,37 +341,36 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) switch (image_id) { case BL32_IMAGE_ID: - bl_mem_params->ep_info.pc = - bl_mem_params->image_info.image_base; - - pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); - assert(pager_mem_params != NULL); - pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE; - pager_mem_params->image_info.image_max_size = - STM32MP_OPTEE_SIZE; - - paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); - assert(paged_mem_params != NULL); - paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + - stm32mp_get_ddr_ns_size(); - paged_mem_params->image_info.image_max_size = - STM32MP_DDR_S_SIZE; - - err = parse_optee_header(&bl_mem_params->ep_info, - &pager_mem_params->image_info, - &paged_mem_params->image_info); - if (err) { - ERROR("OPTEE header parse error.\n"); - panic(); + if (optee_header_is_valid(bl_mem_params->image_info.image_base)) { + /* BL32 is OP-TEE header */ + bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; + pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); + paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); + assert((pager_mem_params != NULL) && (paged_mem_params != NULL)); + + /* Set OP-TEE extra image load areas at run-time */ + pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE; + pager_mem_params->image_info.image_max_size = STM32MP_OPTEE_SIZE; + + paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + + dt_get_ddr_size() - + STM32MP_DDR_S_SIZE - + STM32MP_DDR_SHMEM_SIZE; + paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE; + + err = parse_optee_header(&bl_mem_params->ep_info, + &pager_mem_params->image_info, + &paged_mem_params->image_info); + if (err) { + ERROR("OPTEE header parse error.\n"); + panic(); + } + + /* Set optee boot info from parsed header data */ + bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base; + bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ + bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ } - - /* Set optee boot info from parsed header data */ - bl_mem_params->ep_info.pc = - pager_mem_params->image_info.image_base; - bl_mem_params->ep_info.args.arg0 = - paged_mem_params->image_info.image_base; - bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ - bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ break; case BL33_IMAGE_ID: diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c index 984c6ba08..293ddfd93 100644 --- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c +++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c @@ -27,9 +27,9 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, entry_point_info_t, SECURE | EXECUTABLE | EP_FIRST_EXE), -#if !defined(AARCH32_SP_OPTEE) + /* Updated at runtime if OP-TEE is loaded */ .ep_info.pc = STM32MP_BL32_BASE, -#endif + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS), @@ -37,14 +37,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, IMAGE_ATTRIB_PLAT_SETUP), -#if defined(AARCH32_SP_OPTEE) - /* optee header is loaded in SYSRAM above BL2 */ - .image_info.image_base = STM32MP_OPTEE_BASE, - .image_info.image_max_size = STM32MP_OPTEE_SIZE, -#else + + /* Updated at runtime if OP-TEE is loaded */ .image_info.image_base = STM32MP_BL32_BASE, .image_info.image_max_size = STM32MP_BL32_SIZE, -#endif + .next_handoff_image_id = BL33_IMAGE_ID, }, -- cgit v1.2.3 From 8a5bd3cfed911e493c3030830764c86de6cd77b6 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Wed, 1 Sep 2021 10:25:21 +0200 Subject: docs(ff-a): fix specification naming Rename the FF-A specification to: Arm Firmware Framework for Arm A-profile Signed-off-by: Olivier Deprez Change-Id: I4f9d29409d048e7a49832b95d39d2583c1fb5792 --- docs/components/secure-partition-manager.rst | 108 +++++++++++++-------------- docs/glossary.rst | 4 +- docs/threat_model/threat_model_spm.rst | 4 +- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index a5e7e8ed5..f6a88283e 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -6,59 +6,59 @@ Secure Partition Manager Acronyms ======== -+--------+-----------------------------------+ -| CoT | Chain of Trust | -+--------+-----------------------------------+ -| DMA | Direct Memory Access | -+--------+-----------------------------------+ -| DTB | Device Tree Blob | -+--------+-----------------------------------+ -| DTS | Device Tree Source | -+--------+-----------------------------------+ -| EC | Execution Context | -+--------+-----------------------------------+ -| FIP | Firmware Image Package | -+--------+-----------------------------------+ -| FF-A | Firmware Framework for Armv8-A | -+--------+-----------------------------------+ -| IPA | Intermediate Physical Address | -+--------+-----------------------------------+ -| NWd | Normal World | -+--------+-----------------------------------+ -| ODM | Original Design Manufacturer | -+--------+-----------------------------------+ -| OEM | Original Equipment Manufacturer | -+--------+-----------------------------------+ -| PA | Physical Address | -+--------+-----------------------------------+ -| PE | Processing Element | -+--------+-----------------------------------+ -| PM | Power Management | -+--------+-----------------------------------+ -| PVM | Primary VM | -+--------+-----------------------------------+ -| SMMU | System Memory Management Unit | -+--------+-----------------------------------+ -| SP | Secure Partition | -+--------+-----------------------------------+ -| SPD | Secure Payload Dispatcher | -+--------+-----------------------------------+ -| SPM | Secure Partition Manager | -+--------+-----------------------------------+ -| SPMC | SPM Core | -+--------+-----------------------------------+ -| SPMD | SPM Dispatcher | -+--------+-----------------------------------+ -| SiP | Silicon Provider | -+--------+-----------------------------------+ -| SWd | Secure World | -+--------+-----------------------------------+ -| TLV | Tag-Length-Value | -+--------+-----------------------------------+ -| TOS | Trusted Operating System | -+--------+-----------------------------------+ -| VM | Virtual Machine | -+--------+-----------------------------------+ ++--------+--------------------------------------+ +| CoT | Chain of Trust | ++--------+--------------------------------------+ +| DMA | Direct Memory Access | ++--------+--------------------------------------+ +| DTB | Device Tree Blob | ++--------+--------------------------------------+ +| DTS | Device Tree Source | ++--------+--------------------------------------+ +| EC | Execution Context | ++--------+--------------------------------------+ +| FIP | Firmware Image Package | ++--------+--------------------------------------+ +| FF-A | Firmware Framework for Arm A-profile | ++--------+--------------------------------------+ +| IPA | Intermediate Physical Address | ++--------+--------------------------------------+ +| NWd | Normal World | ++--------+--------------------------------------+ +| ODM | Original Design Manufacturer | ++--------+--------------------------------------+ +| OEM | Original Equipment Manufacturer | ++--------+--------------------------------------+ +| PA | Physical Address | ++--------+--------------------------------------+ +| PE | Processing Element | ++--------+--------------------------------------+ +| PM | Power Management | ++--------+--------------------------------------+ +| PVM | Primary VM | ++--------+--------------------------------------+ +| SMMU | System Memory Management Unit | ++--------+--------------------------------------+ +| SP | Secure Partition | ++--------+--------------------------------------+ +| SPD | Secure Payload Dispatcher | ++--------+--------------------------------------+ +| SPM | Secure Partition Manager | ++--------+--------------------------------------+ +| SPMC | SPM Core | ++--------+--------------------------------------+ +| SPMD | SPM Dispatcher | ++--------+--------------------------------------+ +| SiP | Silicon Provider | ++--------+--------------------------------------+ +| SWd | Secure World | ++--------+--------------------------------------+ +| TLV | Tag-Length-Value | ++--------+--------------------------------------+ +| TOS | Trusted Operating System | ++--------+--------------------------------------+ +| VM | Virtual Machine | ++--------+--------------------------------------+ Foreword ======== @@ -920,7 +920,7 @@ References .. _[1]: -[1] `Arm Firmware Framework for Armv8-A `__ +[1] `Arm Firmware Framework for Arm A-profile `__ .. _[2]: diff --git a/docs/glossary.rst b/docs/glossary.rst index 54820e4b6..f4912f518 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -60,8 +60,8 @@ You can find additional definitions in the `Arm Glossary`_. FDT Flattened Device Tree - FFA - Firmware Framework for A-class processors + FF-A + Firmware Framework for Arm A-profile FIP Firmware Image Package diff --git a/docs/threat_model/threat_model_spm.rst b/docs/threat_model/threat_model_spm.rst index 96d33a2f3..82f9916f0 100644 --- a/docs/threat_model/threat_model_spm.rst +++ b/docs/threat_model/threat_model_spm.rst @@ -8,7 +8,7 @@ This document provides a threat model for the TF-A `Secure Partition Manager`_ (SPM) implementation or more generally the S-EL2 reference firmware running on systems implementing the FEAT_SEL2 (formerly Armv8.4 Secure EL2) architecture extension. The SPM implementation is based on the `Arm Firmware Framework for -Armv8-A`_ specification. +Arm A-profile`_ specification. In brief, the broad FF-A specification and S-EL2 firmware implementation provide: @@ -611,7 +611,7 @@ element of the data flow diagram. *Copyright (c) 2021, Arm Limited. All rights reserved.* -.. _Arm Firmware Framework for Armv8-A: https://developer.arm.com/docs/den0077/latest +.. _Arm Firmware Framework for Arm A-profile: https://developer.arm.com/docs/den0077/latest .. _Secure Partition Manager: ../components/secure-partition-manager.html .. _Generic TF-A threat model: ./threat_model.html#threat-analysis .. _FF-A ACS: https://github.com/ARM-software/ff-a-acs/releases -- cgit v1.2.3 From d9e0586b619b331eb2db75911ca82f927e20bd1c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 2 Jul 2021 09:35:04 +0200 Subject: feat(fdts): add STM32MP1 fw-config DT files Create all boards fw-config DT files. They all include a generic stm32mp15-fw-config.dtsi. Change-Id: Ib9ac8a59e93e01365001b0d11fee41f7c507c08e Signed-off-by: Yann Gautier --- fdts/stm32mp15-fw-config.dtsi | 48 ++++++++++++++++++++++++++++++++ fdts/stm32mp157a-avenger96-fw-config.dts | 7 +++++ fdts/stm32mp157a-dk1-fw-config.dts | 7 +++++ fdts/stm32mp157a-ed1-fw-config.dts | 7 +++++ fdts/stm32mp157a-ev1-fw-config.dts | 7 +++++ fdts/stm32mp157c-dk2-fw-config.dts | 7 +++++ fdts/stm32mp157c-ed1-fw-config.dts | 7 +++++ fdts/stm32mp157c-ev1-fw-config.dts | 7 +++++ fdts/stm32mp157c-lxa-mc1-fw-config.dts | 7 +++++ fdts/stm32mp157c-odyssey-fw-config.dts | 7 +++++ fdts/stm32mp157d-dk1-fw-config.dts | 7 +++++ fdts/stm32mp157d-ed1-fw-config.dts | 7 +++++ fdts/stm32mp157d-ev1-fw-config.dts | 7 +++++ fdts/stm32mp157f-dk2-fw-config.dts | 7 +++++ fdts/stm32mp157f-ed1-fw-config.dts | 7 +++++ fdts/stm32mp157f-ev1-fw-config.dts | 7 +++++ 16 files changed, 153 insertions(+) create mode 100644 fdts/stm32mp15-fw-config.dtsi create mode 100644 fdts/stm32mp157a-avenger96-fw-config.dts create mode 100644 fdts/stm32mp157a-dk1-fw-config.dts create mode 100644 fdts/stm32mp157a-ed1-fw-config.dts create mode 100644 fdts/stm32mp157a-ev1-fw-config.dts create mode 100644 fdts/stm32mp157c-dk2-fw-config.dts create mode 100644 fdts/stm32mp157c-ed1-fw-config.dts create mode 100644 fdts/stm32mp157c-ev1-fw-config.dts create mode 100644 fdts/stm32mp157c-lxa-mc1-fw-config.dts create mode 100644 fdts/stm32mp157c-odyssey-fw-config.dts create mode 100644 fdts/stm32mp157d-dk1-fw-config.dts create mode 100644 fdts/stm32mp157d-ed1-fw-config.dts create mode 100644 fdts/stm32mp157d-ev1-fw-config.dts create mode 100644 fdts/stm32mp157f-dk2-fw-config.dts create mode 100644 fdts/stm32mp157f-ed1-fw-config.dts create mode 100644 fdts/stm32mp157f-ev1-fw-config.dts diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi new file mode 100644 index 000000000..4f2841f8e --- /dev/null +++ b/fdts/stm32mp15-fw-config.dtsi @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + */ + +#include + +#include + +/dts-v1/; + +/ { + dtb-registry { + compatible = "fconf,dyn_cfg-dtb_registry"; + + hw-config { + load-address = <0x0 STM32MP_HW_CONFIG_BASE>; + max-size = ; + id = ; + }; + + nt_fw { + load-address = <0x0 STM32MP_BL33_BASE>; + max-size = ; + id = ; + }; + +#ifdef AARCH32_SP_OPTEE + tos_fw { + load-address = <0x0 STM32MP_OPTEE_BASE>; + max-size = ; + id = ; + }; +#else + tos_fw { + load-address = <0x0 STM32MP_BL32_BASE>; + max-size = ; + id = ; + }; + + tos_fw-config { + load-address = <0x0 STM32MP_BL32_DTB_BASE>; + max-size = ; + id = ; + }; +#endif + }; +}; diff --git a/fdts/stm32mp157a-avenger96-fw-config.dts b/fdts/stm32mp157a-avenger96-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157a-avenger96-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157a-dk1-fw-config.dts b/fdts/stm32mp157a-dk1-fw-config.dts new file mode 100644 index 000000000..83116d103 --- /dev/null +++ b/fdts/stm32mp157a-dk1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157a-ed1-fw-config.dts b/fdts/stm32mp157a-ed1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157a-ed1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157a-ev1-fw-config.dts b/fdts/stm32mp157a-ev1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157a-ev1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157c-dk2-fw-config.dts b/fdts/stm32mp157c-dk2-fw-config.dts new file mode 100644 index 000000000..83116d103 --- /dev/null +++ b/fdts/stm32mp157c-dk2-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157c-ed1-fw-config.dts b/fdts/stm32mp157c-ed1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157c-ed1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157c-ev1-fw-config.dts b/fdts/stm32mp157c-ev1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157c-ev1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157c-lxa-mc1-fw-config.dts b/fdts/stm32mp157c-lxa-mc1-fw-config.dts new file mode 100644 index 000000000..9ee09e93e --- /dev/null +++ b/fdts/stm32mp157c-lxa-mc1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157c-odyssey-fw-config.dts b/fdts/stm32mp157c-odyssey-fw-config.dts new file mode 100644 index 000000000..9ee09e93e --- /dev/null +++ b/fdts/stm32mp157c-odyssey-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157d-dk1-fw-config.dts b/fdts/stm32mp157d-dk1-fw-config.dts new file mode 100644 index 000000000..83116d103 --- /dev/null +++ b/fdts/stm32mp157d-dk1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157d-ed1-fw-config.dts b/fdts/stm32mp157d-ed1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157d-ed1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157d-ev1-fw-config.dts b/fdts/stm32mp157d-ev1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157d-ev1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157f-dk2-fw-config.dts b/fdts/stm32mp157f-dk2-fw-config.dts new file mode 100644 index 000000000..83116d103 --- /dev/null +++ b/fdts/stm32mp157f-dk2-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x20000000 /* 512MB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157f-ed1-fw-config.dts b/fdts/stm32mp157f-ed1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157f-ed1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" diff --git a/fdts/stm32mp157f-ev1-fw-config.dts b/fdts/stm32mp157f-ev1-fw-config.dts new file mode 100644 index 000000000..2abbe50e6 --- /dev/null +++ b/fdts/stm32mp157f-ev1-fw-config.dts @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved + */ + +#define DDR_SIZE 0x40000000 /* 1GB */ +#include "stm32mp15-fw-config.dtsi" -- cgit v1.2.3 From 21e002fb777fad9d02a94dc961f077fb444517fa Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Sun, 27 Sep 2020 20:48:21 +0200 Subject: feat(fdts): add IO policies for STM32MP1 Add the UUID into the io policies node that are retrieved by BL2 using stm32mp_fconf_io.c populate function. Change-Id: I595d5a41a1e0a27fcc02ea2ab5495d9dbf0e6773 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- fdts/stm32mp15-bl2.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi index 36cfd7fcf..da95b25de 100644 --- a/fdts/stm32mp15-bl2.dtsi +++ b/fdts/stm32mp15-bl2.dtsi @@ -27,4 +27,25 @@ /delete-node/ rtc-out2-rmp-pins-0; }; }; + +#if !STM32MP_USE_STM32IMAGE + /* + * UUID's here are UUID RFC 4122 compliant meaning fieds are stored in + * network order (big endian) + */ + + st-io_policies { + fip-handles { + compatible = "st,io-fip-handle"; + fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e"; + bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38"; + bl32_extra1_uuid = "0b70c29b-2a5a-7840-9f65-0a5682738288"; + bl32_extra2_uuid = "8ea87bb1-cfa2-3f4d-85fd-e7bba50220d9"; + bl33_uuid = "d6d0eea7-fcea-d54b-9782-9934f234b6e4"; + hw_cfg_uuid = "08b8f1d9-c9cf-9349-a962-6fbc6b7265cc"; + tos_fw_cfg_uuid = "26257c1a-dbc6-7f47-8d96-c4c4b0248021"; + nt_fw_cfg_uuid = "28da9815-93e8-7e44-ac66-1aaf801550f9"; + }; + }; +#endif /* !STM32MP_USE_STM32IMAGE */ }; -- cgit v1.2.3 From 43de546b909947ab44f104aaee02b98fba70f44c Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Mon, 28 Sep 2020 12:05:28 +0200 Subject: feat(dt-bindings): add STM32MP1 TZC400 bindings Add bindings that will be used to define DDR regions and their access rights. Change-Id: I745a7e580ef2b9e251d53db12c5a0a86dfe34463 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- include/dt-bindings/soc/stm32mp15-tzc400.h | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 include/dt-bindings/soc/stm32mp15-tzc400.h diff --git a/include/dt-bindings/soc/stm32mp15-tzc400.h b/include/dt-bindings/soc/stm32mp15-tzc400.h new file mode 100644 index 000000000..54cd90224 --- /dev/null +++ b/include/dt-bindings/soc/stm32mp15-tzc400.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +/* + * Copyright (C) 2021, STMicroelectronics - All Rights Reserved + */ + +#ifndef _DT_BINDINGS_STM32MP15_TZC400_H +#define _DT_BINDINGS_STM32MP15_TZC400_H + +#include + +#define STM32MP1_TZC_A7_ID U(0) +#define STM32MP1_TZC_M4_ID U(1) +#define STM32MP1_TZC_LCD_ID U(3) +#define STM32MP1_TZC_GPU_ID U(4) +#define STM32MP1_TZC_MDMA_ID U(5) +#define STM32MP1_TZC_DMA_ID U(6) +#define STM32MP1_TZC_USB_HOST_ID U(7) +#define STM32MP1_TZC_USB_OTG_ID U(8) +#define STM32MP1_TZC_SDMMC_ID U(9) +#define STM32MP1_TZC_ETH_ID U(10) +#define STM32MP1_TZC_DAP_ID U(15) + +#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \ + (TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \ + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)) + +#endif /* _DT_BINDINGS_STM32MP15_TZC400_H */ -- cgit v1.2.3 From 1d204ee4ab12893fceb12097bd4f0a074be253b2 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 19 May 2021 18:48:16 +0200 Subject: feat(plat/st): use FIP to load images BL2 still uses the STM32 header binary format to be loaded from ROM code. BL32 and BL33 and their respective device tree files are now put together in a FIP file. One DTB is created for each BL. To reduce their sizes, 2 new dtsi file are in charge of removing useless nodes for a given BL. This is done because BL2 and BL32 share the same device tree files base. The previous way of booting is still available, the compilation flag STM32MP_USE_STM32IMAGE has to be set to 1 in the make command. Some files are duplicated and their names modified with _stm32_ to avoid too much switches in the code. Change-Id: I1ffada0af58486d4cf6044511b51e56b52269817 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- fdts/stm32mp15-bl2.dtsi | 30 + fdts/stm32mp15-bl32.dtsi | 44 ++ plat/st/common/bl2_io_storage.c | 431 ++++---------- plat/st/common/bl2_stm32_io_storage.c | 665 ++++++++++++++++++++++ plat/st/common/include/stm32mp_common.h | 2 + plat/st/common/stm32mp_common.c | 2 + plat/st/stm32mp1/bl2_plat_setup.c | 18 +- plat/st/stm32mp1/include/platform_def.h | 8 +- plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 36 +- plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c | 103 ++++ plat/st/stm32mp1/plat_image_load.c | 10 +- plat/st/stm32mp1/platform.mk | 89 ++- plat/st/stm32mp1/sp_min/sp_min_setup.c | 10 + plat/st/stm32mp1/stm32mp1.S | 4 +- plat/st/stm32mp1/stm32mp1.ld.S | 10 +- plat/st/stm32mp1/stm32mp1_def.h | 53 +- plat/st/stm32mp1/stm32mp1_fip_def.h | 61 ++ plat/st/stm32mp1/stm32mp1_stm32image_def.h | 65 +++ 18 files changed, 1262 insertions(+), 379 deletions(-) create mode 100644 fdts/stm32mp15-bl2.dtsi create mode 100644 fdts/stm32mp15-bl32.dtsi create mode 100644 plat/st/common/bl2_stm32_io_storage.c create mode 100644 plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c create mode 100644 plat/st/stm32mp1/stm32mp1_fip_def.h create mode 100644 plat/st/stm32mp1/stm32mp1_stm32image_def.h diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi new file mode 100644 index 000000000..36cfd7fcf --- /dev/null +++ b/fdts/stm32mp15-bl2.dtsi @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2020-2021 - All Rights Reserved + */ + +/ { + cpus { + /delete-node/ cpu@1; + }; + + /delete-node/ psci; + + soc { + /delete-node/ timer@40006000; + /delete-node/ timer@44006000; + /delete-node/ pwr_mcu@50001014; + /delete-node/ cryp@54001000; + /delete-node/ rng@54003000; + /delete-node/ spi@5c001000; + /delete-node/ rtc@5c004000; + /delete-node/ etzpc@5c007000; + /delete-node/ stgen@5c008000; + /delete-node/ i2c@5c009000; + /delete-node/ tamp@5c00a000; + + pin-controller@50002000 { + /delete-node/ rtc-out2-rmp-pins-0; + }; + }; +}; diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi new file mode 100644 index 000000000..f005d563b --- /dev/null +++ b/fdts/stm32mp15-bl32.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (C) STMicroelectronics 2020-2021 - All Rights Reserved + */ + +/ { + aliases { + /delete-property/ mmc0; + /delete-property/ mmc1; + }; + + cpus { + /delete-node/ cpu@1; + }; + + /delete-node/ psci; + + soc { + /delete-node/ usb-otg@49000000; + /delete-node/ hash@54002000; + /delete-node/ memory-controller@58002000; + /delete-node/ spi@58003000; + /delete-node/ sdmmc@58005000; + /delete-node/ sdmmc@58007000; + /delete-node/ usbphyc@5a006000; + /delete-node/ spi@5c001000; + /delete-node/ stgen@5c008000; + /delete-node/ i2c@5c009000; + + pin-controller@50002000 { + /delete-node/ fmc-0; + /delete-node/ qspi-clk-0; + /delete-node/ qspi-bk1-0; + /delete-node/ qspi-bk2-0; + /delete-node/ sdmmc1-b4-0; + /delete-node/ sdmmc1-dir-0; + /delete-node/ sdmmc2-b4-0; + /delete-node/ sdmmc2-b4-1; + /delete-node/ sdmmc2-d47-0; + /delete-node/ usbotg_hs-0; + /delete-node/ usbotg-fs-dp-dm-0; + }; + }; +}; diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index e6032674e..01c289db8 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -7,13 +7,11 @@ #include #include -#include - #include #include #include #include -#include +#include #include #include #include @@ -22,29 +20,27 @@ #include #include #include -#include #include #include #include #include #include #include +#include + +#include /* IO devices */ -#ifndef AARCH32_SP_OPTEE -static const io_dev_connector_t *dummy_dev_con; -static uintptr_t dummy_dev_handle; -static uintptr_t dummy_dev_spec; -#endif +uintptr_t fip_dev_handle; +uintptr_t storage_dev_handle; -static uintptr_t image_dev_handle; -static uintptr_t storage_dev_handle; +static const io_dev_connector_t *fip_dev_con; #if STM32MP_SDMMC || STM32MP_EMMC static struct mmc_device_info mmc_info; static io_block_spec_t gpt_block_spec = { - .offset = 0, - .length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */ + .offset = 0U, + .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ }; static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); @@ -62,30 +58,6 @@ static const io_block_dev_spec_t mmc_block_dev_spec = { .block_size = MMC_BLOCK_SIZE, }; -#if STM32MP_EMMC_BOOT -static io_block_spec_t emmc_boot_ssbl_block_spec = { - .offset = PLAT_EMMC_BOOT_SSBL_OFFSET, - .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */ -}; - -static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = { - /* It's used as temp buffer in block driver */ - .buffer = { - .offset = (size_t)&block_buffer, - .length = MMC_BLOCK_SIZE, - }, - .ops = { - .read = mmc_boot_part_read_blocks, - .write = NULL, - }, - .block_size = MMC_BLOCK_SIZE, -}; -#endif - -static struct io_mmc_dev_spec mmc_device_spec = { - .use_boot_part = false, -}; - static const io_dev_connector_t *mmc_dev_con; #endif /* STM32MP_SDMMC || STM32MP_EMMC */ @@ -103,6 +75,7 @@ static io_mtd_dev_spec_t nand_dev_spec = { .ops = { .init = nand_raw_init, .read = nand_read, + .seek = nand_seek_bb }, }; @@ -114,6 +87,7 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { .ops = { .init = spi_nand_init, .read = nand_read, + .seek = nand_seek_bb }, }; #endif @@ -122,76 +96,42 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif -#ifdef AARCH32_SP_OPTEE -static const struct stm32image_part_info optee_header_partition_spec = { - .name = OPTEE_HEADER_IMAGE_NAME, - .binary_type = OPTEE_HEADER_BINARY_TYPE, +static const io_uuid_spec_t bl33_partition_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33 }; -static const struct stm32image_part_info optee_core_partition_spec = { - .name = OPTEE_CORE_IMAGE_NAME, - .binary_type = OPTEE_CORE_BINARY_TYPE, +static const io_uuid_spec_t tos_fw_config_uuid_spec = { + .uuid = UUID_TOS_FW_CONFIG, }; -static const struct stm32image_part_info optee_paged_partition_spec = { - .name = OPTEE_PAGED_IMAGE_NAME, - .binary_type = OPTEE_PAGED_BINARY_TYPE, -}; -#else -static const io_block_spec_t bl32_block_spec = { - .offset = BL32_BASE, - .length = STM32MP_BL32_SIZE -}; -#endif - -static const struct stm32image_part_info bl33_partition_spec = { - .name = BL33_IMAGE_NAME, - .binary_type = BL33_BINARY_TYPE, +static const io_uuid_spec_t hw_config_uuid_spec = { + .uuid = UUID_HW_CONFIG, }; -enum { - IMG_IDX_BL33, #ifdef AARCH32_SP_OPTEE - IMG_IDX_OPTEE_HEADER, - IMG_IDX_OPTEE_CORE, - IMG_IDX_OPTEE_PAGED, -#endif - IMG_IDX_NUM +static const io_uuid_spec_t optee_header_partition_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32 }; -static struct stm32image_device_info stm32image_dev_info_spec __unused = { - .lba_size = MMC_BLOCK_SIZE, - .part_info[IMG_IDX_BL33] = { - .name = BL33_IMAGE_NAME, - .binary_type = BL33_BINARY_TYPE, - }, -#ifdef AARCH32_SP_OPTEE - .part_info[IMG_IDX_OPTEE_HEADER] = { - .name = OPTEE_HEADER_IMAGE_NAME, - .binary_type = OPTEE_HEADER_BINARY_TYPE, - }, - .part_info[IMG_IDX_OPTEE_CORE] = { - .name = OPTEE_CORE_IMAGE_NAME, - .binary_type = OPTEE_CORE_BINARY_TYPE, - }, - .part_info[IMG_IDX_OPTEE_PAGED] = { - .name = OPTEE_PAGED_IMAGE_NAME, - .binary_type = OPTEE_PAGED_BINARY_TYPE, - }, -#endif +static const io_uuid_spec_t optee_core_partition_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1 }; -static io_block_spec_t stm32image_block_spec = { - .offset = 0, - .length = 0, +static const io_uuid_spec_t optee_paged_partition_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2 +}; +#else +static const io_uuid_spec_t bl32_partition_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32 }; +#endif -static const io_dev_connector_t *stm32image_dev_con __unused; +static io_block_spec_t image_block_spec = { + .offset = 0U, + .length = 0U, +}; -#ifndef AARCH32_SP_OPTEE -static int open_dummy(const uintptr_t spec); -#endif -static int open_image(const uintptr_t spec); +static int open_fip(const uintptr_t spec); static int open_storage(const uintptr_t spec); struct plat_io_policy { @@ -201,33 +141,48 @@ struct plat_io_policy { }; static const struct plat_io_policy policies[] = { + [FIP_IMAGE_ID] = { + .dev_handle = &storage_dev_handle, + .image_spec = (uintptr_t)&image_block_spec, + .check = open_storage + }, #ifdef AARCH32_SP_OPTEE [BL32_IMAGE_ID] = { - .dev_handle = &image_dev_handle, + .dev_handle = &fip_dev_handle, .image_spec = (uintptr_t)&optee_header_partition_spec, - .check = open_image + .check = open_fip }, [BL32_EXTRA1_IMAGE_ID] = { - .dev_handle = &image_dev_handle, + .dev_handle = &fip_dev_handle, .image_spec = (uintptr_t)&optee_core_partition_spec, - .check = open_image + .check = open_fip }, [BL32_EXTRA2_IMAGE_ID] = { - .dev_handle = &image_dev_handle, + .dev_handle = &fip_dev_handle, .image_spec = (uintptr_t)&optee_paged_partition_spec, - .check = open_image + .check = open_fip }, #else [BL32_IMAGE_ID] = { - .dev_handle = &dummy_dev_handle, - .image_spec = (uintptr_t)&bl32_block_spec, - .check = open_dummy + .dev_handle = &fip_dev_handle, + .image_spec = (uintptr_t)&bl32_partition_spec, + .check = open_fip }, #endif [BL33_IMAGE_ID] = { - .dev_handle = &image_dev_handle, + .dev_handle = &fip_dev_handle, .image_spec = (uintptr_t)&bl33_partition_spec, - .check = open_image + .check = open_fip + }, + [TOS_FW_CONFIG_ID] = { + .dev_handle = &fip_dev_handle, + .image_spec = (uintptr_t)&tos_fw_config_uuid_spec, + .check = open_fip + }, + [HW_CONFIG_ID] = { + .dev_handle = &fip_dev_handle, + .image_spec = (uintptr_t)&hw_config_uuid_spec, + .check = open_fip }, #if STM32MP_SDMMC || STM32MP_EMMC [GPT_IMAGE_ID] = { @@ -236,23 +191,11 @@ static const struct plat_io_policy policies[] = { .check = open_storage }, #endif - [STM32_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&stm32image_block_spec, - .check = open_storage - } }; -#ifndef AARCH32_SP_OPTEE -static int open_dummy(const uintptr_t spec) +static int open_fip(const uintptr_t spec) { - return io_dev_init(dummy_dev_handle, 0); -} -#endif - -static int open_image(const uintptr_t spec) -{ - return io_dev_init(image_dev_handle, 0); + return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); } static int open_storage(const uintptr_t spec) @@ -260,38 +203,6 @@ static int open_storage(const uintptr_t spec) return io_dev_init(storage_dev_handle, 0); } -#if STM32MP_EMMC_BOOT -static uint32_t get_boot_part_ssbl_header(void) -{ - uint32_t magic = 0; - int io_result; - size_t bytes_read; - - io_result = register_io_dev_block(&mmc_dev_con); - if (io_result != 0) { - panic(); - } - - io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec, - &storage_dev_handle); - assert(io_result == 0); - - io_result = io_open(storage_dev_handle, (uintptr_t) &emmc_boot_ssbl_block_spec, - &image_dev_handle); - assert(io_result == 0); - - io_result = io_read(image_dev_handle, (uintptr_t) &magic, sizeof(magic), - &bytes_read); - assert(io_result == 0); - assert(bytes_read == sizeof(magic)); - - io_result = io_dev_close(storage_dev_handle); - assert(io_result == 0); - - return magic; -} -#endif - static void print_boot_device(boot_api_context_t *boot_context) { switch (boot_context->boot_interface_selected) { @@ -311,7 +222,8 @@ static void print_boot_device(boot_api_context_t *boot_context) INFO("Using SPI NAND\n"); break; default: - ERROR("Boot interface not found\n"); + ERROR("Boot interface %u not found\n", + boot_context->boot_interface_selected); panic(); break; } @@ -321,29 +233,12 @@ static void print_boot_device(boot_api_context_t *boot_context) } } -static void stm32image_io_setup(void) -{ - int io_result __unused; - - io_result = register_io_dev_stm32image(&stm32image_dev_con); - assert(io_result == 0); - - io_result = io_dev_open(stm32image_dev_con, - (uintptr_t)&stm32image_dev_info_spec, - &image_dev_handle); - assert(io_result == 0); -} - #if STM32MP_SDMMC || STM32MP_EMMC static void boot_mmc(enum mmc_device_type mmc_dev_type, uint16_t boot_interface_instance) { int io_result __unused; - uint8_t idx; - struct stm32image_part_info *part; struct stm32_sdmmc2_params params; - const partition_entry_t *entry __unused; - uint32_t magic __unused; zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); @@ -375,26 +270,6 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, panic(); } - stm32image_dev_info_spec.device_size = - stm32_sdmmc2_mmc_get_device_size(); - -#if STM32MP_EMMC_BOOT - magic = get_boot_part_ssbl_header(); - - if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) { - VERBOSE("%s, header found, jump to emmc load\n", __func__); - idx = IMG_IDX_BL33; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET; - part->bkp_offset = 0U; - mmc_device_spec.use_boot_part = true; - - goto emmc_boot; - } else { - WARN("%s: Can't find STM32 header on a boot partition\n", __func__); - } -#endif - /* Open MMC as a block device to read GPT table */ io_result = register_io_dev_block(&mmc_dev_con); if (io_result != 0) { @@ -404,37 +279,6 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type, io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, &storage_dev_handle); assert(io_result == 0); - - partition_init(GPT_IMAGE_ID); - - io_result = io_dev_close(storage_dev_handle); - assert(io_result == 0); - - for (idx = 0U; idx < IMG_IDX_NUM; idx++) { - part = &stm32image_dev_info_spec.part_info[idx]; - entry = get_partition_entry(part->name); - if (entry == NULL) { - ERROR("Partition %s not found\n", part->name); - panic(); - } - - part->part_offset = entry->start; - part->bkp_offset = 0U; - } - -#if STM32MP_EMMC_BOOT -emmc_boot: -#endif - /* - * Re-open MMC with io_mmc, for better perfs compared to - * io_block. - */ - io_result = register_io_dev_mmc(&mmc_dev_con); - assert(io_result == 0); - - io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec, - &storage_dev_handle); - assert(io_result == 0); } #endif /* STM32MP_SDMMC || STM32MP_EMMC */ @@ -442,8 +286,6 @@ emmc_boot: static void boot_spi_nor(boot_api_context_t *boot_context) { int io_result __unused; - uint8_t idx; - struct stm32image_part_info *part; io_result = stm32_qspi_init(); assert(io_result == 0); @@ -456,30 +298,6 @@ static void boot_spi_nor(boot_api_context_t *boot_context) (uintptr_t)&spi_nor_dev_spec, &storage_dev_handle); assert(io_result == 0); - - stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; - - idx = IMG_IDX_BL33; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NOR_BL33_OFFSET; - part->bkp_offset = 0U; - -#ifdef AARCH32_SP_OPTEE - idx = IMG_IDX_OPTEE_HEADER; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NOR_TEEH_OFFSET; - part->bkp_offset = 0U; - - idx = IMG_IDX_OPTEE_PAGED; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NOR_TEED_OFFSET; - part->bkp_offset = 0U; - - idx = IMG_IDX_OPTEE_CORE; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NOR_TEEX_OFFSET; - part->bkp_offset = 0U; -#endif } #endif /* STM32MP_SPI_NOR */ @@ -487,8 +305,6 @@ static void boot_spi_nor(boot_api_context_t *boot_context) static void boot_fmc2_nand(boot_api_context_t *boot_context) { int io_result __unused; - uint8_t idx; - struct stm32image_part_info *part; io_result = stm32_fmc2_init(); assert(io_result == 0); @@ -501,30 +317,6 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context) io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, &storage_dev_handle); assert(io_result == 0); - - stm32image_dev_info_spec.device_size = nand_dev_spec.device_size; - - idx = IMG_IDX_BL33; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_BL33_OFFSET; - part->bkp_offset = nand_dev_spec.erase_size; - -#ifdef AARCH32_SP_OPTEE - idx = IMG_IDX_OPTEE_HEADER; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEEH_OFFSET; - part->bkp_offset = nand_dev_spec.erase_size; - - idx = IMG_IDX_OPTEE_PAGED; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEED_OFFSET; - part->bkp_offset = nand_dev_spec.erase_size; - - idx = IMG_IDX_OPTEE_CORE; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEEX_OFFSET; - part->bkp_offset = nand_dev_spec.erase_size; -#endif } #endif /* STM32MP_RAW_NAND */ @@ -532,8 +324,6 @@ static void boot_fmc2_nand(boot_api_context_t *boot_context) static void boot_spi_nand(boot_api_context_t *boot_context) { int io_result __unused; - uint8_t idx; - struct stm32image_part_info *part; io_result = stm32_qspi_init(); assert(io_result == 0); @@ -546,31 +336,6 @@ static void boot_spi_nand(boot_api_context_t *boot_context) (uintptr_t)&spi_nand_dev_spec, &storage_dev_handle); assert(io_result == 0); - - stm32image_dev_info_spec.device_size = - spi_nand_dev_spec.device_size; - - idx = IMG_IDX_BL33; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_BL33_OFFSET; - part->bkp_offset = spi_nand_dev_spec.erase_size; - -#ifdef AARCH32_SP_OPTEE - idx = IMG_IDX_OPTEE_HEADER; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEEH_OFFSET; - part->bkp_offset = spi_nand_dev_spec.erase_size; - - idx = IMG_IDX_OPTEE_PAGED; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEED_OFFSET; - part->bkp_offset = spi_nand_dev_spec.erase_size; - - idx = IMG_IDX_OPTEE_CORE; - part = &stm32image_dev_info_spec.part_info[idx]; - part->part_offset = STM32MP_NAND_TEEX_OFFSET; - part->bkp_offset = spi_nand_dev_spec.erase_size; -#endif } #endif /* STM32MP_SPI_NAND */ @@ -584,53 +349,45 @@ void stm32mp_io_setup(void) if ((boot_context->boot_partition_used_toboot == 1U) || (boot_context->boot_partition_used_toboot == 2U)) { - INFO("Boot used partition fsbl%d\n", + INFO("Boot used partition fsbl%u\n", boot_context->boot_partition_used_toboot); } -#ifndef AARCH32_SP_OPTEE - io_result = register_io_dev_dummy(&dummy_dev_con); + io_result = register_io_dev_fip(&fip_dev_con); assert(io_result == 0); - io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, - &dummy_dev_handle); - assert(io_result == 0); -#endif + io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); switch (boot_context->boot_interface_selected) { #if STM32MP_SDMMC case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: dmbsy(); boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); - stm32image_io_setup(); break; #endif #if STM32MP_EMMC case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: dmbsy(); boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); - stm32image_io_setup(); break; #endif #if STM32MP_SPI_NOR case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: dmbsy(); boot_spi_nor(boot_context); - stm32image_io_setup(); break; #endif #if STM32MP_RAW_NAND case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: dmbsy(); boot_fmc2_nand(boot_context); - stm32image_io_setup(); break; #endif #if STM32MP_SPI_NAND case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: dmbsy(); boot_spi_nand(boot_context); - stm32image_io_setup(); break; #endif @@ -642,6 +399,60 @@ void stm32mp_io_setup(void) } } +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + static bool gpt_init_done __unused; + uint16_t boot_itf = stm32mp_get_boot_itf_selected(); + + switch (boot_itf) { +#if STM32MP_SDMMC || STM32MP_EMMC + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + if (!gpt_init_done) { + const partition_entry_t *entry; + + partition_init(GPT_IMAGE_ID); + entry = get_partition_entry(FIP_IMAGE_NAME); + if (entry == NULL) { + ERROR("Could NOT find the %s partition!\n", + FIP_IMAGE_NAME); + return -ENOENT; + } + + image_block_spec.offset = entry->start; + image_block_spec.length = entry->length; + + gpt_init_done = true; + } + + break; +#endif + +#if STM32MP_RAW_NAND || STM32MP_SPI_NAND +#if STM32MP_RAW_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: +#endif +#if STM32MP_SPI_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: +#endif + image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; + break; +#endif + +#if STM32MP_SPI_NOR + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: + image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; + break; +#endif + + default: + ERROR("FIP Not found\n"); + panic(); + } + + return 0; +} + /* * Return an IO device handle and specification which can be used to access * an image. Use this to enforce platform load policy. diff --git a/plat/st/common/bl2_stm32_io_storage.c b/plat/st/common/bl2_stm32_io_storage.c new file mode 100644 index 000000000..2d68a5028 --- /dev/null +++ b/plat/st/common/bl2_stm32_io_storage.c @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* IO devices */ +#ifndef AARCH32_SP_OPTEE +static const io_dev_connector_t *dummy_dev_con; +static uintptr_t dummy_dev_handle; +static uintptr_t dummy_dev_spec; +#endif + +static uintptr_t image_dev_handle; +static uintptr_t storage_dev_handle; + +#if STM32MP_SDMMC || STM32MP_EMMC +static struct mmc_device_info mmc_info; +static io_block_spec_t gpt_block_spec = { + .offset = 0U, + .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ +}; + +static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); + +static const io_block_dev_spec_t mmc_block_dev_spec = { + /* It's used as temp buffer in block driver */ + .buffer = { + .offset = (size_t)&block_buffer, + .length = MMC_BLOCK_SIZE, + }, + .ops = { + .read = mmc_read_blocks, + .write = NULL, + }, + .block_size = MMC_BLOCK_SIZE, +}; + +#if STM32MP_EMMC_BOOT +static io_block_spec_t emmc_boot_ssbl_block_spec = { + .offset = PLAT_EMMC_BOOT_SSBL_OFFSET, + .length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */ +}; + +static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = { + /* It's used as temp buffer in block driver */ + .buffer = { + .offset = (size_t)&block_buffer, + .length = MMC_BLOCK_SIZE, + }, + .ops = { + .read = mmc_boot_part_read_blocks, + .write = NULL, + }, + .block_size = MMC_BLOCK_SIZE, +}; +#endif + +static struct io_mmc_dev_spec mmc_device_spec = { + .use_boot_part = false, +}; + +static const io_dev_connector_t *mmc_dev_con; +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR +static io_mtd_dev_spec_t spi_nor_dev_spec = { + .ops = { + .init = spi_nor_init, + .read = spi_nor_read, + }, +}; +#endif + +#if STM32MP_RAW_NAND +static io_mtd_dev_spec_t nand_dev_spec = { + .ops = { + .init = nand_raw_init, + .read = nand_read, + }, +}; + +static const io_dev_connector_t *nand_dev_con; +#endif + +#if STM32MP_SPI_NAND +static io_mtd_dev_spec_t spi_nand_dev_spec = { + .ops = { + .init = spi_nand_init, + .read = nand_read, + }, +}; +#endif + +#if STM32MP_SPI_NAND || STM32MP_SPI_NOR +static const io_dev_connector_t *spi_dev_con; +#endif + +#ifdef AARCH32_SP_OPTEE +static const struct stm32image_part_info optee_header_partition_spec = { + .name = OPTEE_HEADER_IMAGE_NAME, + .binary_type = OPTEE_HEADER_BINARY_TYPE, +}; + +static const struct stm32image_part_info optee_core_partition_spec = { + .name = OPTEE_CORE_IMAGE_NAME, + .binary_type = OPTEE_CORE_BINARY_TYPE, +}; + +static const struct stm32image_part_info optee_paged_partition_spec = { + .name = OPTEE_PAGED_IMAGE_NAME, + .binary_type = OPTEE_PAGED_BINARY_TYPE, +}; +#else +static const io_block_spec_t bl32_block_spec = { + .offset = BL32_BASE, + .length = STM32MP_BL32_SIZE +}; +#endif + +static const struct stm32image_part_info bl33_partition_spec = { + .name = BL33_IMAGE_NAME, + .binary_type = BL33_BINARY_TYPE, +}; + +enum { + IMG_IDX_BL33, +#ifdef AARCH32_SP_OPTEE + IMG_IDX_OPTEE_HEADER, + IMG_IDX_OPTEE_CORE, + IMG_IDX_OPTEE_PAGED, +#endif + IMG_IDX_NUM +}; + +static struct stm32image_device_info stm32image_dev_info_spec __unused = { + .lba_size = MMC_BLOCK_SIZE, + .part_info[IMG_IDX_BL33] = { + .name = BL33_IMAGE_NAME, + .binary_type = BL33_BINARY_TYPE, + }, +#ifdef AARCH32_SP_OPTEE + .part_info[IMG_IDX_OPTEE_HEADER] = { + .name = OPTEE_HEADER_IMAGE_NAME, + .binary_type = OPTEE_HEADER_BINARY_TYPE, + }, + .part_info[IMG_IDX_OPTEE_CORE] = { + .name = OPTEE_CORE_IMAGE_NAME, + .binary_type = OPTEE_CORE_BINARY_TYPE, + }, + .part_info[IMG_IDX_OPTEE_PAGED] = { + .name = OPTEE_PAGED_IMAGE_NAME, + .binary_type = OPTEE_PAGED_BINARY_TYPE, + }, +#endif +}; + +static io_block_spec_t stm32image_block_spec = { + .offset = 0U, + .length = 0U, +}; + +static const io_dev_connector_t *stm32image_dev_con __unused; + +#ifndef AARCH32_SP_OPTEE +static int open_dummy(const uintptr_t spec); +#endif +static int open_image(const uintptr_t spec); +static int open_storage(const uintptr_t spec); + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { +#ifdef AARCH32_SP_OPTEE + [BL32_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_header_partition_spec, + .check = open_image + }, + [BL32_EXTRA1_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_core_partition_spec, + .check = open_image + }, + [BL32_EXTRA2_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&optee_paged_partition_spec, + .check = open_image + }, +#else + [BL32_IMAGE_ID] = { + .dev_handle = &dummy_dev_handle, + .image_spec = (uintptr_t)&bl32_block_spec, + .check = open_dummy + }, +#endif + [BL33_IMAGE_ID] = { + .dev_handle = &image_dev_handle, + .image_spec = (uintptr_t)&bl33_partition_spec, + .check = open_image + }, +#if STM32MP_SDMMC || STM32MP_EMMC + [GPT_IMAGE_ID] = { + .dev_handle = &storage_dev_handle, + .image_spec = (uintptr_t)&gpt_block_spec, + .check = open_storage + }, +#endif + [STM32_IMAGE_ID] = { + .dev_handle = &storage_dev_handle, + .image_spec = (uintptr_t)&stm32image_block_spec, + .check = open_storage + } +}; + +#ifndef AARCH32_SP_OPTEE +static int open_dummy(const uintptr_t spec) +{ + return io_dev_init(dummy_dev_handle, 0); +} +#endif + +static int open_image(const uintptr_t spec) +{ + return io_dev_init(image_dev_handle, 0); +} + +static int open_storage(const uintptr_t spec) +{ + return io_dev_init(storage_dev_handle, 0); +} + +#if STM32MP_EMMC_BOOT +static uint32_t get_boot_part_ssbl_header(void) +{ + uint32_t magic = 0U; + int io_result; + size_t bytes_read; + + io_result = register_io_dev_block(&mmc_dev_con); + if (io_result != 0) { + panic(); + } + + io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec, + &storage_dev_handle); + assert(io_result == 0); + + io_result = io_open(storage_dev_handle, (uintptr_t)&emmc_boot_ssbl_block_spec, + &image_dev_handle); + assert(io_result == 0); + + io_result = io_read(image_dev_handle, (uintptr_t)&magic, sizeof(magic), + &bytes_read); + assert(io_result == 0); + assert(bytes_read == sizeof(magic)); + + io_result = io_dev_close(storage_dev_handle); + assert(io_result == 0); + + return magic; +} +#endif + +static void print_boot_device(boot_api_context_t *boot_context) +{ + switch (boot_context->boot_interface_selected) { + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + INFO("Using SDMMC\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + INFO("Using EMMC\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: + INFO("Using QSPI NOR\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + INFO("Using FMC NAND\n"); + break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: + INFO("Using SPI NAND\n"); + break; + default: + ERROR("Boot interface not found\n"); + panic(); + break; + } + + if (boot_context->boot_interface_instance != 0U) { + INFO(" Instance %d\n", boot_context->boot_interface_instance); + } +} + +static void stm32image_io_setup(void) +{ + int io_result __unused; + + io_result = register_io_dev_stm32image(&stm32image_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(stm32image_dev_con, + (uintptr_t)&stm32image_dev_info_spec, + &image_dev_handle); + assert(io_result == 0); +} + +#if STM32MP_SDMMC || STM32MP_EMMC +static void boot_mmc(enum mmc_device_type mmc_dev_type, + uint16_t boot_interface_instance) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + struct stm32_sdmmc2_params params; + const partition_entry_t *entry __unused; + uint32_t magic __unused; + + zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); + + mmc_info.mmc_dev_type = mmc_dev_type; + + switch (boot_interface_instance) { + case 1: + params.reg_base = STM32MP_SDMMC1_BASE; + break; + case 2: + params.reg_base = STM32MP_SDMMC2_BASE; + break; + case 3: + params.reg_base = STM32MP_SDMMC3_BASE; + break; + default: + WARN("SDMMC instance not found, using default\n"); + if (mmc_dev_type == MMC_IS_SD) { + params.reg_base = STM32MP_SDMMC1_BASE; + } else { + params.reg_base = STM32MP_SDMMC2_BASE; + } + break; + } + + params.device_info = &mmc_info; + if (stm32_sdmmc2_mmc_init(¶ms) != 0) { + ERROR("SDMMC%u init failed\n", boot_interface_instance); + panic(); + } + + stm32image_dev_info_spec.device_size = + stm32_sdmmc2_mmc_get_device_size(); + +#if STM32MP_EMMC_BOOT + magic = get_boot_part_ssbl_header(); + + if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) { + VERBOSE("%s, header found, jump to emmc load\n", __func__); + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET; + part->bkp_offset = 0U; + mmc_device_spec.use_boot_part = true; + + goto emmc_boot; + } else { + WARN("%s: Can't find STM32 header on a boot partition\n", __func__); + } +#endif + + /* Open MMC as a block device to read GPT table */ + io_result = register_io_dev_block(&mmc_dev_con); + if (io_result != 0) { + panic(); + } + + io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + partition_init(GPT_IMAGE_ID); + + io_result = io_dev_close(storage_dev_handle); + assert(io_result == 0); + + for (idx = 0U; idx < IMG_IDX_NUM; idx++) { + part = &stm32image_dev_info_spec.part_info[idx]; + entry = get_partition_entry(part->name); + if (entry == NULL) { + ERROR("Partition %s not found\n", part->name); + panic(); + } + + part->part_offset = entry->start; + part->bkp_offset = 0U; + } + +#if STM32MP_EMMC_BOOT +emmc_boot: +#endif + /* + * Re-open MMC with io_mmc, for better perfs compared to + * io_block. + */ + io_result = register_io_dev_mmc(&mmc_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec, + &storage_dev_handle); + assert(io_result == 0); +} +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + +#if STM32MP_SPI_NOR +static void boot_spi_nor(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); + + io_result = register_io_dev_mtd(&spi_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(spi_dev_con, + (uintptr_t)&spi_nor_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_BL33_OFFSET; + part->bkp_offset = 0U; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEH_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEED_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEX_OFFSET; + part->bkp_offset = 0U; +#endif +} +#endif /* STM32MP_SPI_NOR */ + +#if STM32MP_RAW_NAND +static void boot_fmc2_nand(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_fmc2_init(); + assert(io_result == 0); + + /* Register the IO device on this platform */ + io_result = register_io_dev_mtd(&nand_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = nand_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_BL33_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEH_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = nand_dev_spec.erase_size; +#endif +} +#endif /* STM32MP_RAW_NAND */ + +#if STM32MP_SPI_NAND +static void boot_spi_nand(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); + + io_result = register_io_dev_mtd(&spi_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(spi_dev_con, + (uintptr_t)&spi_nand_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = + spi_nand_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_BL33_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEH_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEED_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; + + idx = IMG_IDX_OPTEE_CORE; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NAND_TEEX_OFFSET; + part->bkp_offset = spi_nand_dev_spec.erase_size; +#endif +} +#endif /* STM32MP_SPI_NAND */ + +void stm32mp_io_setup(void) +{ + int io_result __unused; + boot_api_context_t *boot_context = + (boot_api_context_t *)stm32mp_get_boot_ctx_address(); + + print_boot_device(boot_context); + + if ((boot_context->boot_partition_used_toboot == 1U) || + (boot_context->boot_partition_used_toboot == 2U)) { + INFO("Boot used partition fsbl%u\n", + boot_context->boot_partition_used_toboot); + } + +#ifndef AARCH32_SP_OPTEE + io_result = register_io_dev_dummy(&dummy_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(dummy_dev_con, dummy_dev_spec, + &dummy_dev_handle); + assert(io_result == 0); +#endif + + switch (boot_context->boot_interface_selected) { +#if STM32MP_SDMMC + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: + dmbsy(); + boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); + stm32image_io_setup(); + break; +#endif +#if STM32MP_EMMC + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: + dmbsy(); + boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); + stm32image_io_setup(); + break; +#endif +#if STM32MP_SPI_NOR + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: + dmbsy(); + boot_spi_nor(boot_context); + stm32image_io_setup(); + break; +#endif +#if STM32MP_RAW_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: + dmbsy(); + boot_fmc2_nand(boot_context); + stm32image_io_setup(); + break; +#endif +#if STM32MP_SPI_NAND + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: + dmbsy(); + boot_spi_nand(boot_context); + stm32image_io_setup(); + break; +#endif + + default: + ERROR("Boot interface %d not supported\n", + boot_context->boot_interface_selected); + panic(); + break; + } +} + +/* + * Return an IO device handle and specification which can be used to access + * an image. Use this to enforce platform load policy. + */ +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int rc; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + rc = policy->check(policy->image_spec); + if (rc == 0) { + *image_spec = policy->image_spec; + *dev_handle = *(policy->dev_handle); + } + + return rc; +} diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index edced71aa..8a5fe48ad 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -95,6 +95,7 @@ unsigned long stm32mp_clk_get_rate(unsigned long id); /* Initialise the IO layer and register platform IO devices */ void stm32mp_io_setup(void); +#if STM32MP_USE_STM32IMAGE /* * Check that the STM32 header of a .stm32 binary image is valid * @param header: pointer to the stm32 image header @@ -102,6 +103,7 @@ void stm32mp_io_setup(void); * @return: 0 on success, negative value in case of error */ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer); +#endif /* STM32MP_USE_STM32IMAGE */ /* Functions to map DDR in MMU with non-cacheable attribute, and unmap it */ int stm32mp_map_ddr_non_cacheable(void); diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 5e5958baa..17ac145ab 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -76,6 +76,7 @@ bool stm32mp_lock_available(void) return (read_sctlr() & c_m_bits) == c_m_bits; } +#if STM32MP_USE_STM32IMAGE int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) { uint32_t i; @@ -109,6 +110,7 @@ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) return 0; } +#endif /* STM32MP_USE_STM32IMAGE */ int stm32mp_map_ddr_non_cacheable(void) { diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index ac2a1e282..83e5cd136 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -151,11 +151,13 @@ void bl2_platform_setup(void) panic(); } +#if STM32MP_USE_STM32IMAGE #ifdef AARCH32_SP_OPTEE INFO("BL2 runs OP-TEE setup\n"); #else INFO("BL2 runs SP_MIN setup\n"); #endif +#endif /* STM32MP_USE_STM32IMAGE */ } void bl2_el3_plat_arch_setup(void) @@ -173,6 +175,7 @@ void bl2_el3_plat_arch_setup(void) BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_SECURE); +#if STM32MP_USE_STM32IMAGE #ifdef AARCH32_SP_OPTEE mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE, STM32MP_OPTEE_SIZE, @@ -183,6 +186,8 @@ void bl2_el3_plat_arch_setup(void) BL32_LIMIT - BL32_BASE, MT_RO_DATA | MT_SECURE); #endif +#endif /* STM32MP_USE_STM32IMAGE */ + /* Prevent corruption of preloaded Device Tree */ mmap_add_region(DTB_BASE, DTB_BASE, DTB_LIMIT - DTB_BASE, @@ -324,7 +329,6 @@ skip_console_init: stm32mp_io_setup(); } -#if defined(AARCH32_SP_OPTEE) /******************************************************************************* * This function can be used by the platforms to update/use image * information for given `image_id`. @@ -334,8 +338,8 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) int err = 0; bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); bl_mem_params_node_t *bl32_mem_params; - bl_mem_params_node_t *pager_mem_params; - bl_mem_params_node_t *paged_mem_params; + bl_mem_params_node_t *pager_mem_params __unused; + bl_mem_params_node_t *paged_mem_params __unused; assert(bl_mem_params != NULL); @@ -348,6 +352,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); assert((pager_mem_params != NULL) && (paged_mem_params != NULL)); +#if STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE) /* Set OP-TEE extra image load areas at run-time */ pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE; pager_mem_params->image_info.image_max_size = STM32MP_OPTEE_SIZE; @@ -357,6 +362,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE; paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE; +#endif /* STM32MP_USE_STM32IMAGE && defined(AARCH32_SP_OPTEE) */ err = parse_optee_header(&bl_mem_params->ep_info, &pager_mem_params->image_info, @@ -370,6 +376,11 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) bl_mem_params->ep_info.args.arg0 = paged_mem_params->image_info.image_base; bl_mem_params->ep_info.args.arg1 = 0; /* Unused */ bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */ + } else { +#if !STM32MP_USE_STM32IMAGE + bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; +#endif /* !STM32MP_USE_STM32IMAGE */ + bl_mem_params->ep_info.args.arg0 = 0; } break; @@ -391,4 +402,3 @@ void bl2_el3_plat_prepare_exit(void) { stm32mp1_security_setup(); } -#endif diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h index 2d7d36945..8a065bf75 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -25,6 +25,7 @@ #define PLATFORM_STACK_SIZE 0xC00 #endif +#if STM32MP_USE_STM32IMAGE #ifdef AARCH32_SP_OPTEE #define OPTEE_HEADER_IMAGE_NAME "teeh" #define OPTEE_CORE_IMAGE_NAME "teex" @@ -37,6 +38,9 @@ /* SSBL = second stage boot loader */ #define BL33_IMAGE_NAME "ssbl" #define BL33_BINARY_TYPE U(0x0) +#else /* STM32MP_USE_STM32IMAGE */ +#define FIP_IMAGE_NAME "fip" +#endif /* STM32MP_USE_STM32IMAGE */ #define STM32MP_PRIMARY_CPU U(0x0) #define STM32MP_SECONDARY_CPU U(0x1) @@ -67,7 +71,7 @@ /******************************************************************************* * BL32 specific defines. ******************************************************************************/ -#ifndef AARCH32_SP_OPTEE +#if STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) #if ENABLE_PIE #define BL32_BASE 0 #define BL32_LIMIT STM32MP_BL32_SIZE @@ -76,7 +80,7 @@ #define BL32_LIMIT (STM32MP_BL32_BASE + \ STM32MP_BL32_SIZE) #endif -#endif +#endif /* STM32MP_USE_STM32IMAGE || defined(IMAGE_BL32) */ /******************************************************************************* * BL33 specific defines. diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c index 293ddfd93..0bc2b797e 100644 --- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c +++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c @@ -4,12 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include - #include #include #include +#include + /******************************************************************************* * Following descriptor provides BL image/ep information that gets used * by BL2 to load the images and also subset of this information is @@ -75,7 +75,37 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = INVALID_IMAGE_ID, }, #endif /* AARCH32_SP_OPTEE */ + /* Fill HW_CONFIG related information if it exists */ + { + .image_id = HW_CONFIG_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, + NON_SECURE | NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, + 0U), + .image_info.image_base = STM32MP_HW_CONFIG_BASE, + .image_info.image_max_size = + PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_HW_CONFIG_BASE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#if !defined(AARCH32_SP_OPTEE) + { + .image_id = TOS_FW_CONFIG_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, + 0U), + + .image_info.image_base = STM32MP_BL32_DTB_BASE, + .image_info.image_max_size = STM32MP_BL32_DTB_SIZE, + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif /* Fill BL33 related information */ { .image_id = BL33_IMAGE_ID, @@ -90,7 +120,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { DISABLE_ALL_EXCEPTIONS), SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, 0), + VERSION_2, image_info_t, 0U), .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - diff --git a/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c new file mode 100644 index 000000000..4fce55a9e --- /dev/null +++ b/plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include + +/******************************************************************************* + * Following descriptor provides BL image/ep information that gets used + * by BL2 to load the images and also subset of this information is + * passed to next BL image. The image loading sequence is managed by + * populating the images in required loading order. The image execution + * sequence is managed by populating the `next_handoff_image_id` with + * the next executable image id. + ******************************************************************************/ +static bl_mem_params_node_t bl2_mem_params_descs[] = { + /* Fill BL32 related information */ + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + + /* Updated at runtime if OP-TEE is loaded */ + .ep_info.pc = STM32MP_BL32_BASE, + + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), + + /* Updated at runtime if OP-TEE is loaded */ + .image_info.image_base = STM32MP_BL32_BASE, + .image_info.image_max_size = STM32MP_BL32_SIZE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, + +#if defined(AARCH32_SP_OPTEE) + /* Fill BL32 external 1 image related information */ + { + .image_id = BL32_EXTRA1_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + /* Fill BL32 external 2 image related information */ + { + .image_id = BL32_EXTRA2_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, +#endif /* AARCH32_SP_OPTEE */ + + /* Fill BL33 related information */ + { + .image_id = BL33_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + NON_SECURE | EXECUTABLE), + + .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, + .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, + SPSR_E_LITTLE, + DISABLE_ALL_EXCEPTIONS), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0U), + + .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, + .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - + (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs) diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c index 6d7af741a..36a3a1c39 100644 --- a/plat/st/stm32mp1/plat_image_load.c +++ b/plat/st/stm32mp1/plat_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,12 +23,14 @@ void plat_flush_next_bl_params(void) ******************************************************************************/ bl_load_info_t *plat_get_bl_image_load_info(void) { +#if STM32MP_USE_STM32IMAGE bl_mem_params_node_t *bl33 = get_bl_mem_params_node(BL33_IMAGE_ID); uint32_t ddr_ns_size = stm32mp_get_ddr_ns_size(); /* Max size is non-secure DDR end address minus image_base */ bl33->image_info.image_max_size = STM32MP_DDR_BASE + ddr_ns_size - bl33->image_info.image_base; +#endif /* STM32MP_USE_STM32IMAGE */ return get_bl_load_info_from_mem_params_desc(); } @@ -38,5 +40,9 @@ bl_load_info_t *plat_get_bl_image_load_info(void) ******************************************************************************/ bl_params_t *plat_get_next_bl_params(void) { - return get_next_bl_params_from_mem_params_desc(); + bl_params_t *bl_params = get_next_bl_params_from_mem_params_desc(); + + populate_next_bl_params_config(bl_params); + + return bl_params; } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 1693135e5..9e72b50f0 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -9,7 +9,14 @@ ARM_WITH_NEON := yes BL2_AT_EL3 := 1 USE_COHERENT_MEM := 0 +# Allow TF-A to concatenate BL2 & BL32 binaries in a single file, +# share DTB file between BL2 and BL32 +# If it is set to 0, then FIP is used +STM32MP_USE_STM32IMAGE ?= 0 + +ifneq ($(STM32MP_USE_STM32IMAGE),1) ENABLE_PIE := 1 +endif STM32_TF_VERSION ?= 0 @@ -29,8 +36,10 @@ STM32_TF_A_COPIES := 2 STM32_BL33_PARTS_NUM := 1 ifeq ($(AARCH32_SP),optee) STM32_RUNTIME_PARTS_NUM := 3 -else +else ifeq ($(STM32MP_USE_STM32IMAGE),1) STM32_RUNTIME_PARTS_NUM := 0 +else +STM32_RUNTIME_PARTS_NUM := 1 endif PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + \ $(STM32_BL33_PARTS_NUM) + \ @@ -46,7 +55,21 @@ STM32MP_EMMC_BOOT ?= 0 # Device tree DTB_FILE_NAME ?= stm32mp157c-ev1.dtb +ifeq ($(STM32MP_USE_STM32IMAGE),1) +ifeq ($(AARCH32_SP),optee) +BL2_DTSI := stm32mp15-bl2.dtsi +FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) +else FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(DTB_FILE_NAME))) +endif +else +BL2_DTSI := stm32mp15-bl2.dtsi +FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME))) +ifeq ($(AARCH32_SP),sp_min) +BL32_DTSI := stm32mp15-bl32.dtsi +FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME))) +endif +endif DTC_FLAGS += -Wno-unit_address_vs_reg # Macros and rules to build TF binary @@ -66,6 +89,26 @@ STM32IMAGEPATH ?= tools/stm32image STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT} STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c +ifneq (${STM32MP_USE_STM32IMAGE},1) +FIP_DEPS += dtbs +STM32MP_HW_CONFIG := ${BL33_CFG} +# Add the HW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config)) +ifeq ($(AARCH32_SP),sp_min) +STM32MP_TOS_FW_CONFIG := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dtb,$(DTB_FILE_NAME))) +$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_TOS_FW_CONFIG},--tos-fw-config)) +else +# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images +# in the FIP if the platform requires. +ifneq ($(BL32_EXTRA1),) +$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1)) +endif +ifneq ($(BL32_EXTRA2),) +$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2)) +endif +endif +endif + # Enable flags for C files $(eval $(call assert_booleans,\ $(sort \ @@ -76,6 +119,7 @@ $(eval $(call assert_booleans,\ STM32MP_SPI_NOR \ STM32MP_EMMC_BOOT \ PLAT_XLAT_TABLES_DYNAMIC \ + STM32MP_USE_STM32IMAGE \ ))) $(eval $(call assert_numerics,\ @@ -95,6 +139,7 @@ $(eval $(call add_defines,\ PLAT_XLAT_TABLES_DYNAMIC \ STM32_TF_A_COPIES \ PLAT_PARTITION_MAX_ENTRIES \ + STM32MP_USE_STM32IMAGE \ ))) # Include paths and source files @@ -138,14 +183,22 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ plat/st/stm32mp1/stm32mp1_security.c \ plat/st/stm32mp1/stm32mp1_syscfg.c +ifneq (${STM32MP_USE_STM32IMAGE},1) +BL2_SOURCES += drivers/io/io_fip.c \ + plat/st/common/bl2_io_storage.c \ + plat/st/stm32mp1/plat_bl2_mem_params_desc.c +else +BL2_SOURCES += drivers/io/io_dummy.c \ + drivers/st/io/io_stm32image.c \ + plat/st/common/bl2_stm32_io_storage.c \ + plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c +endif + BL2_SOURCES += drivers/io/io_block.c \ - drivers/io/io_dummy.c \ drivers/io/io_mtd.c \ drivers/io/io_storage.c \ drivers/st/crypto/stm32_hash.c \ - drivers/st/io/io_stm32image.c \ plat/st/common/stm32mp_auth.c \ - plat/st/common/bl2_io_storage.c \ plat/st/stm32mp1/bl2_plat_setup.c ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),) @@ -187,12 +240,9 @@ BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ drivers/st/ddr/stm32mp1_ram.c BL2_SOURCES += common/desc_image_load.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ plat/st/stm32mp1/plat_image_load.c -ifeq ($(AARCH32_SP),optee) BL2_SOURCES += lib/optee/optee_utils.c -endif # Compilation rules .PHONY: check_dtc_version stm32image clean_stm32image check_boot_device @@ -230,12 +280,35 @@ check_dtc_version: false; \ fi - +ifeq ($(STM32MP_USE_STM32IMAGE)-$(AARCH32_SP),1-sp_min) ${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%.dtb plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} + @echo " AS stm32mp1.S" + ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ + -DDTB_BIN_PATH=\"$<\" \ + -c $(word 2,$^) -o $@ +else +# Create DTB file for BL2 +${BUILD_PLAT}/fdts/%-bl2.dts: fdts/%.dts fdts/${BL2_DTSI} | ${BUILD_PLAT} fdt_dirs + @echo '#include "$(patsubst fdts/%,%,$<)"' > $@ + @echo '#include "${BL2_DTSI}"' >> $@ + +${BUILD_PLAT}/fdts/%-bl2.dtb: ${BUILD_PLAT}/fdts/%-bl2.dts + +ifeq ($(AARCH32_SP),sp_min) +# Create DTB file for BL32 +${BUILD_PLAT}/fdts/%-bl32.dts: fdts/%.dts fdts/${BL32_DTSI} | ${BUILD_PLAT} fdt_dirs + @echo '#include "$(patsubst fdts/%,%,$<)"' > $@ + @echo '#include "${BL32_DTSI}"' >> $@ + +${BUILD_PLAT}/fdts/%-bl32.dtb: ${BUILD_PLAT}/fdts/%-bl32.dts +endif + +${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32mp1.S bl2 @echo " AS stm32mp1.S" ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \ -DDTB_BIN_PATH=\"$<\" \ -c plat/st/stm32mp1/stm32mp1.S -o $@ +endif $(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index 334f914a4..e30febb4e 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -140,6 +140,16 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, while (bl_params != NULL) { if (bl_params->image_id == BL33_IMAGE_ID) { bl33_image_ep_info = *bl_params->ep_info; + /* + * Check if hw_configuration is given to BL32 and + * share it to BL33. + */ + if (arg2 != 0U) { + bl33_image_ep_info.args.arg0 = 0U; + bl33_image_ep_info.args.arg1 = 0U; + bl33_image_ep_info.args.arg2 = arg2; + } + break; } diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S index 7255fe5aa..85caa0a80 100644 --- a/plat/st/stm32mp1/stm32mp1.S +++ b/plat/st/stm32mp1/stm32mp1.S @@ -1,13 +1,15 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#if STM32MP_USE_STM32IMAGE #ifdef BL32_BIN_PATH .section .bl32_image .incbin BL32_BIN_PATH #endif +#endif /* STM32MP_USE_STM32IMAGE */ .section .bl2_image .incbin BL2_BIN_PATH diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S index b347baddf..945de99e5 100644 --- a/plat/st/stm32mp1/stm32mp1.ld.S +++ b/plat/st/stm32mp1/stm32mp1.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,7 +43,11 @@ SECTIONS * The strongest and only alignment contraint is MMU 4K page. * Indeed as images below will be removed, 4K pages will be re-used. */ +#if STM32MP_USE_STM32IMAGE . = ( STM32MP_DTB_BASE - STM32MP_BINARY_BASE ); +#else + . = ( STM32MP_BL2_DTB_BASE - STM32MP_BINARY_BASE ); +#endif /* STM32MP_USE_STM32IMAGE */ __DTB_IMAGE_START__ = .; *(.dtb_image*) __DTB_IMAGE_END__ = .; @@ -58,7 +62,7 @@ SECTIONS *(.bl2_image*) __BL2_IMAGE_END__ = .; -#ifndef AARCH32_SP_OPTEE +#if STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) /* * bl32 will be settled by bl2. * The strongest and only alignment constraint is 8 words to simplify @@ -68,7 +72,7 @@ SECTIONS __BL32_IMAGE_START__ = .; *(.bl32_image*) __BL32_IMAGE_END__ = .; -#endif +#endif /* STM32MP_USE_STM32IMAGE && !defined(AARCH32_SP_OPTEE) */ __DATA_END__ = .; } >RAM diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 155d63db2..aa76703fc 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -28,6 +28,12 @@ #include #endif +#if !STM32MP_USE_STM32IMAGE +#include "stm32mp1_fip_def.h" +#else /* STM32MP_USE_STM32IMAGE */ +#include "stm32mp1_stm32image_def.h" +#endif /* STM32MP_USE_STM32IMAGE */ + /******************************************************************************* * CHIP ID ******************************************************************************/ @@ -111,26 +117,6 @@ enum ddr_type { (STM32MP_PARAM_LOAD_SIZE + \ STM32MP_HEADER_SIZE)) -#ifdef AARCH32_SP_OPTEE -#define STM32MP_BL32_SIZE U(0) - -#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE - -#define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \ - STM32MP_OPTEE_BASE) -#else -#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */ -#endif - -#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ - STM32MP_SEC_SYSRAM_SIZE - \ - STM32MP_BL32_SIZE) - -#define STM32MP_BL2_SIZE U(0x0001A000) /* 100 KB for BL2 */ - -#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ - STM32MP_BL2_SIZE) - /* BL2 and BL32/sp_min require 4 tables */ #define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */ @@ -141,38 +127,13 @@ enum ddr_type { #if defined(IMAGE_BL2) #define MAX_MMAP_REGIONS 11 #endif -#if defined(IMAGE_BL32) - #define MAX_MMAP_REGIONS 6 -#endif - -/* DTB initialization value */ -#define STM32MP_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ - -#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ - STM32MP_DTB_SIZE) #define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000)) +#define STM32MP_BL33_MAX_SIZE U(0x400000) /* Define maximum page size for NAND devices */ #define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000) -/******************************************************************************* - * STM32MP1 RAW partition offset for MTD devices - ******************************************************************************/ -#define STM32MP_NOR_BL33_OFFSET U(0x00080000) -#ifdef AARCH32_SP_OPTEE -#define STM32MP_NOR_TEEH_OFFSET U(0x00280000) -#define STM32MP_NOR_TEED_OFFSET U(0x002C0000) -#define STM32MP_NOR_TEEX_OFFSET U(0x00300000) -#endif - -#define STM32MP_NAND_BL33_OFFSET U(0x00200000) -#ifdef AARCH32_SP_OPTEE -#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) -#define STM32MP_NAND_TEED_OFFSET U(0x00680000) -#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) -#endif - /******************************************************************************* * STM32MP1 device/io map related constants (used for MMU) ******************************************************************************/ diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h new file mode 100644 index 000000000..5b9a3cb0b --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_fip_def.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP1_FIP_DEF_H +#define STM32MP1_FIP_DEF_H + +#define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ +#define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ +#define STM32MP_BL32_SIZE U(0x00019000) /* 100 KB for BL32 */ +#define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ +#define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000) /* 256 KB for HW config DTB */ + +#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ + STM32MP_BL2_SIZE) + +#define STM32MP_BL2_DTB_BASE (STM32MP_BL2_BASE - \ + STM32MP_BL2_DTB_SIZE) + +#define STM32MP_BL32_DTB_BASE STM32MP_SYSRAM_BASE + +#define STM32MP_BL32_BASE (STM32MP_BL32_DTB_BASE + \ + STM32MP_BL32_DTB_SIZE) + +#if defined(IMAGE_BL2) +#define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE +#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE +#endif +#if defined(IMAGE_BL32) +#define STM32MP_DTB_SIZE STM32MP_BL32_DTB_SIZE +#define STM32MP_DTB_BASE STM32MP_BL32_DTB_BASE +#endif + +#ifdef AARCH32_SP_OPTEE +#define STM32MP_OPTEE_BASE STM32MP_SEC_SYSRAM_BASE + +#define STM32MP_OPTEE_SIZE (STM32MP_BL2_DTB_BASE - \ + STM32MP_OPTEE_BASE) +#endif + +#define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \ + STM32MP_BL33_MAX_SIZE) + +/* + * MAX_MMAP_REGIONS is usually: + * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup + */ +#if defined(IMAGE_BL32) +#define MAX_MMAP_REGIONS 10 +#endif + +/******************************************************************************* + * STM32MP1 RAW partition offset for MTD devices + ******************************************************************************/ +#define STM32MP_NOR_FIP_OFFSET U(0x00080000) +#define STM32MP_NAND_FIP_OFFSET U(0x00200000) + +#endif /* STM32MP1_FIP_DEF_H */ diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h new file mode 100644 index 000000000..8bae56ae5 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP1_STM32IMAGE_DEF_H +#define STM32MP1_STM32IMAGE_DEF_H + +#define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ +#define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ + +#ifdef AARCH32_SP_OPTEE +#define STM32MP_BL32_BASE STM32MP_SEC_SYSRAM_BASE + +#define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ + STM32MP_BL2_SIZE) + +/* OP-TEE loads from SYSRAM base to BL2 DTB start address */ +#define STM32MP_OPTEE_BASE STM32MP_BL32_BASE +#define STM32MP_OPTEE_SIZE (STM32MP_SEC_SYSRAM_SIZE - \ + STM32MP_BL2_SIZE - STM32MP_DTB_SIZE) +#define STM32MP_BL32_SIZE STM32MP_OPTEE_SIZE +#else /* AARCH32_SP_OPTEE */ +#define STM32MP_BL32_SIZE U(0x00019000) /* 96 KB for BL32 */ + +#define STM32MP_BL32_BASE (STM32MP_SEC_SYSRAM_BASE + \ + STM32MP_SEC_SYSRAM_SIZE - \ + STM32MP_BL32_SIZE) + +#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \ + STM32MP_BL2_SIZE) +#endif /* AARCH32_SP_OPTEE */ + +/* DTB initialization value */ +#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \ + STM32MP_DTB_SIZE) + +/* + * MAX_MMAP_REGIONS is usually: + * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup + */ +#if defined(IMAGE_BL32) +#define MAX_MMAP_REGIONS 6 +#endif + +/******************************************************************************* + * STM32MP1 RAW partition offset for MTD devices + ******************************************************************************/ +#define STM32MP_NOR_BL33_OFFSET U(0x00080000) +#ifdef AARCH32_SP_OPTEE +#define STM32MP_NOR_TEEH_OFFSET U(0x00280000) +#define STM32MP_NOR_TEED_OFFSET U(0x002C0000) +#define STM32MP_NOR_TEEX_OFFSET U(0x00300000) +#endif + +#define STM32MP_NAND_BL33_OFFSET U(0x00200000) +#ifdef AARCH32_SP_OPTEE +#define STM32MP_NAND_TEEH_OFFSET U(0x00600000) +#define STM32MP_NAND_TEED_OFFSET U(0x00680000) +#define STM32MP_NAND_TEEX_OFFSET U(0x00700000) +#endif + +#endif /* STM32MP1_STM32IMAGE_DEF_H */ -- cgit v1.2.3 From 18b415be9d631b3e0c3a3caacc5f02edb9413f6b Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 18 Jun 2021 11:33:26 +0200 Subject: feat(plat/st): improve FIP image loading from MMC Instead of using a scratch buffer of 512 bytes, we can directly use the image address and max size. The mmc_block_dev_spec struct info is then overwritten for each image with this info, except FW_CONFIG and GPT table which will still use the scratch buffer. This allows using multiple blocks read on MMC, and so improves the boot time. A cache invalidate is required for the remaining data not used from the first and last blocks read. It is not required for FW_CONFIG_ID, as it is in scratch buffer in SYSRAM, and also because bl_mem_params struct is overwritten in this case. This should also not be done if the image is not found (OP-TEE extra binaries when using SP_min). Change-Id: If3ecfdfe35bb9db66284036ca49c4bd1be4fd121 Signed-off-by: Yann Gautier --- plat/st/common/bl2_io_storage.c | 8 +++++++- plat/st/stm32mp1/bl2_plat_setup.c | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 01c289db8..6c7618aba 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,7 @@ static io_block_spec_t gpt_block_spec = { static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); -static const io_block_dev_spec_t mmc_block_dev_spec = { +static io_block_dev_spec_t mmc_block_dev_spec = { /* It's used as temp buffer in block driver */ .buffer = { .offset = (size_t)&block_buffer, @@ -423,6 +424,11 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id) image_block_spec.length = entry->length; gpt_init_done = true; + } else { + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + + mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; + mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; } break; diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 83e5cd136..53177f628 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -395,6 +396,19 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) break; } +#if STM32MP_SDMMC || STM32MP_EMMC + /* + * Invalidate remaining data read from MMC but not flushed by load_image_flush(). + * We take the worst case which is 2 MMC blocks. + */ + if ((image_id != FW_CONFIG_ID) && + ((bl_mem_params->image_info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U)) { + inv_dcache_range(bl_mem_params->image_info.image_base + + bl_mem_params->image_info.image_size, + 2U * MMC_BLOCK_SIZE); + } +#endif /* STM32MP_SDMMC || STM32MP_EMMC */ + return err; } -- cgit v1.2.3 From 29332bcd680ce7e5f864813d9a900360f5e35d41 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 6 Jul 2021 10:00:44 +0200 Subject: feat(plat/st): use FCONF to configure platform Add required code to support FCONF on STM32MP1 platform. The new FW_CONFIG DT file will be inside the FIP, and loaded by BL2. It will be used to configure the addresses where to load other binaries. BL2 should be agnostic of which BL32 is in the FIP (OP-TEE or SP_min), so optee_utils.c is always compiled, and some OP-TEE flags are removed. Change-Id: Id957b49b0117864136250bfc416664f815043ada Signed-off-by: Yann Gautier --- plat/st/common/bl2_io_storage.c | 9 ++++ plat/st/stm32mp1/bl2_plat_setup.c | 72 +++++++++++++++++++++++++++++ plat/st/stm32mp1/plat_bl2_mem_params_desc.c | 51 ++++++++++---------- plat/st/stm32mp1/platform.mk | 10 ++++ plat/st/stm32mp1/sp_min/sp_min_setup.c | 11 +++-- plat/st/stm32mp1/stm32mp1_def.h | 7 --- plat/st/stm32mp1/stm32mp1_fip_def.h | 8 ++++ plat/st/stm32mp1/stm32mp1_stm32image_def.h | 8 ++++ 8 files changed, 139 insertions(+), 37 deletions(-) diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 6c7618aba..817f44972 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -97,6 +97,10 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif +static const io_uuid_spec_t fw_config_uuid_spec = { + .uuid = UUID_FW_CONFIG, +}; + static const io_uuid_spec_t bl33_partition_spec = { .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33 }; @@ -175,6 +179,11 @@ static const struct plat_io_policy policies[] = { .image_spec = (uintptr_t)&bl33_partition_spec, .check = open_fip }, + [FW_CONFIG_ID] = { + .dev_handle = &fip_dev_handle, + .image_spec = (uintptr_t)&fw_config_uuid_spec, + .check = open_fip + }, [TOS_FW_CONFIG_ID] = { .dev_handle = &fip_dev_handle, .image_spec = (uintptr_t)&tos_fw_config_uuid_spec, diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 53177f628..9053a2541 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -24,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -341,10 +344,76 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) bl_mem_params_node_t *bl32_mem_params; bl_mem_params_node_t *pager_mem_params __unused; bl_mem_params_node_t *paged_mem_params __unused; +#if !STM32MP_USE_STM32IMAGE + const struct dyn_cfg_dtb_info_t *config_info; + bl_mem_params_node_t *tos_fw_mem_params; + unsigned int i; + unsigned long long ddr_top __unused; + const unsigned int image_ids[] = { + BL32_IMAGE_ID, + BL33_IMAGE_ID, + HW_CONFIG_ID, + TOS_FW_CONFIG_ID, + }; +#endif /* !STM32MP_USE_STM32IMAGE */ assert(bl_mem_params != NULL); switch (image_id) { +#if !STM32MP_USE_STM32IMAGE + case FW_CONFIG_ID: + /* Set global DTB info for fixed fw_config information */ + set_config_info(STM32MP_FW_CONFIG_BASE, STM32MP_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID); + fconf_populate("FW_CONFIG", STM32MP_FW_CONFIG_BASE); + + /* Iterate through all the fw config IDs */ + for (i = 0U; i < ARRAY_SIZE(image_ids); i++) { + bl_mem_params = get_bl_mem_params_node(image_ids[i]); + assert(bl_mem_params != NULL); + + config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, image_ids[i]); + if (config_info == NULL) { + continue; + } + + bl_mem_params->image_info.image_base = config_info->config_addr; + bl_mem_params->image_info.image_max_size = config_info->config_max_size; + + bl_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; + + switch (image_ids[i]) { + case BL32_IMAGE_ID: + bl_mem_params->ep_info.pc = config_info->config_addr; + + /* In case of OPTEE, initialize address space with tos_fw addr */ + pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); + pager_mem_params->image_info.image_base = config_info->config_addr; + pager_mem_params->image_info.image_max_size = + config_info->config_max_size; + + /* Init base and size for pager if exist */ + paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); + paged_mem_params->image_info.image_base = STM32MP_DDR_BASE + + (dt_get_ddr_size() - STM32MP_DDR_S_SIZE - + STM32MP_DDR_SHMEM_SIZE); + paged_mem_params->image_info.image_max_size = STM32MP_DDR_S_SIZE; + break; + + case BL33_IMAGE_ID: + bl_mem_params->ep_info.pc = config_info->config_addr; + break; + + case HW_CONFIG_ID: + case TOS_FW_CONFIG_ID: + break; + + default: + return -EINVAL; + } + } + break; +#endif /* !STM32MP_USE_STM32IMAGE */ + case BL32_IMAGE_ID: if (optee_header_is_valid(bl_mem_params->image_info.image_base)) { /* BL32 is OP-TEE header */ @@ -380,6 +449,9 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) } else { #if !STM32MP_USE_STM32IMAGE bl_mem_params->ep_info.pc = bl_mem_params->image_info.image_base; + tos_fw_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID); + bl_mem_params->image_info.image_max_size += + tos_fw_mem_params->image_info.image_max_size; #endif /* !STM32MP_USE_STM32IMAGE */ bl_mem_params->ep_info.args.arg0 = 0; } diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c index 0bc2b797e..7963c4a97 100644 --- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c +++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c @@ -19,6 +19,22 @@ * the next executable image id. ******************************************************************************/ static bl_mem_params_node_t bl2_mem_params_descs[] = { + /* Fill FW_CONFIG related information if it exists */ + { + .image_id = FW_CONFIG_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), + + .image_info.image_base = STM32MP_FW_CONFIG_BASE, + .image_info.image_max_size = STM32MP_FW_CONFIG_MAX_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + /* Fill BL32 related information */ { .image_id = BL32_IMAGE_ID, @@ -27,25 +43,17 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, entry_point_info_t, SECURE | EXECUTABLE | EP_FIRST_EXE), - /* Updated at runtime if OP-TEE is loaded */ - .ep_info.pc = STM32MP_BL32_BASE, - .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS), SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, - IMAGE_ATTRIB_PLAT_SETUP), - - /* Updated at runtime if OP-TEE is loaded */ - .image_info.image_base = STM32MP_BL32_BASE, - .image_info.image_max_size = STM32MP_BL32_SIZE, + IMAGE_ATTRIB_SKIP_LOADING), .next_handoff_image_id = BL33_IMAGE_ID, }, -#if defined(AARCH32_SP_OPTEE) /* Fill BL32 external 1 image related information */ { .image_id = BL32_EXTRA1_IMAGE_ID, @@ -74,7 +82,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .next_handoff_image_id = INVALID_IMAGE_ID, }, -#endif /* AARCH32_SP_OPTEE */ + /* Fill HW_CONFIG related information if it exists */ { .image_id = HW_CONFIG_ID, @@ -83,15 +91,12 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { NON_SECURE | NON_EXECUTABLE), SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, VERSION_2, image_info_t, - 0U), - - .image_info.image_base = STM32MP_HW_CONFIG_BASE, - .image_info.image_max_size = - PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_HW_CONFIG_BASE, + IMAGE_ATTRIB_SKIP_LOADING), .next_handoff_image_id = INVALID_IMAGE_ID, }, -#if !defined(AARCH32_SP_OPTEE) + + /* Fill TOS_FW_CONFIG related information if it exists */ { .image_id = TOS_FW_CONFIG_ID, SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, @@ -99,13 +104,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { SECURE | NON_EXECUTABLE), SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, VERSION_2, image_info_t, - 0U), + IMAGE_ATTRIB_SKIP_LOADING), - .image_info.image_base = STM32MP_BL32_DTB_BASE, - .image_info.image_max_size = STM32MP_BL32_DTB_SIZE, .next_handoff_image_id = INVALID_IMAGE_ID, }, -#endif + /* Fill BL33 related information */ { .image_id = BL33_IMAGE_ID, @@ -114,17 +117,13 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE), - .ep_info.pc = PLAT_STM32MP_NS_IMAGE_OFFSET, .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM, SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS), SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, - VERSION_2, image_info_t, 0U), - - .image_info.image_base = PLAT_STM32MP_NS_IMAGE_OFFSET, - .image_info.image_max_size = STM32MP_DDR_MAX_SIZE - - (PLAT_STM32MP_NS_IMAGE_OFFSET - STM32MP_DDR_BASE), + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), .next_handoff_image_id = INVALID_IMAGE_ID, } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 9e72b50f0..d415a1ecc 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -70,6 +70,7 @@ BL32_DTSI := stm32mp15-bl32.dtsi FDT_SOURCES += $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl32.dts,$(DTB_FILE_NAME))) endif endif +DTC_CPPFLAGS += ${INCLUDES} DTC_FLAGS += -Wno-unit_address_vs_reg # Macros and rules to build TF binary @@ -92,6 +93,13 @@ STM32IMAGE_SRC := ${STM32IMAGEPATH}/stm32image.c ifneq (${STM32MP_USE_STM32IMAGE},1) FIP_DEPS += dtbs STM32MP_HW_CONFIG := ${BL33_CFG} +STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME)) +STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME) +ifneq (${AARCH32_SP},none) +FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME))) +endif +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config)) # Add the HW_CONFIG to FIP and specify the same to certtool $(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_HW_CONFIG},--hw-config)) ifeq ($(AARCH32_SP),sp_min) @@ -185,6 +193,8 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ ifneq (${STM32MP_USE_STM32IMAGE},1) BL2_SOURCES += drivers/io/io_fip.c \ + lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ plat/st/stm32mp1/plat_bl2_mem_params_desc.c else diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c index e30febb4e..1495e027c 100644 --- a/plat/st/stm32mp1/sp_min/sp_min_setup.c +++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c @@ -45,6 +45,7 @@ void sp_min_plat_fiq_handler(uint32_t id) { switch (id & INT_ID_MASK) { case STM32MP1_IRQ_TZC400: + tzc400_init(STM32MP1_TZC_BASE); (void)tzc400_it_handler(); panic(); break; @@ -117,6 +118,11 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, struct dt_node_info dt_uart_info; int result; bl_params_t *params_from_bl2 = (bl_params_t *)arg0; +#if STM32MP_USE_STM32IMAGE + uintptr_t dt_addr = STM32MP_DTB_BASE; +#else + uintptr_t dt_addr = arg1; +#endif /* Imprecise aborts can be masked in NonSecure */ write_scr(read_scr() | SCR_AW_BIT); @@ -156,7 +162,7 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl_params = bl_params->next_params_info; } - if (dt_open_and_check(STM32MP_DTB_BASE) < 0) { + if (dt_open_and_check(dt_addr) < 0) { panic(); } @@ -195,9 +201,6 @@ void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void sp_min_platform_setup(void) { - /* Initialize tzc400 after DDR initialization */ - stm32mp1_security_setup(); - generic_delay_timer_init(); stm32mp1_gic_init(); diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index aa76703fc..f14bf8c4c 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -87,13 +87,6 @@ /* DDR configuration */ #define STM32MP_DDR_BASE U(0xC0000000) #define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */ -#ifdef AARCH32_SP_OPTEE -#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ -#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ -#else -#define STM32MP_DDR_S_SIZE U(0) -#define STM32MP_DDR_SHMEM_SIZE U(0) -#endif /* DDR power initializations */ #ifndef __ASSEMBLER__ diff --git a/plat/st/stm32mp1/stm32mp1_fip_def.h b/plat/st/stm32mp1/stm32mp1_fip_def.h index 5b9a3cb0b..d8561dcc0 100644 --- a/plat/st/stm32mp1/stm32mp1_fip_def.h +++ b/plat/st/stm32mp1/stm32mp1_fip_def.h @@ -7,10 +7,14 @@ #ifndef STM32MP1_FIP_DEF_H #define STM32MP1_FIP_DEF_H +#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ +#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ + #define STM32MP_BL2_SIZE U(0x0001B000) /* 108 KB for BL2 */ #define STM32MP_BL2_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ #define STM32MP_BL32_SIZE U(0x00019000) /* 100 KB for BL32 */ #define STM32MP_BL32_DTB_SIZE U(0x00005000) /* 20 KB for DTB */ +#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE /* 4 KB for FCONF DTB */ #define STM32MP_HW_CONFIG_MAX_SIZE U(0x40000) /* 256 KB for HW config DTB */ #define STM32MP_BL2_BASE (STM32MP_SEC_SYSRAM_BASE + \ @@ -25,6 +29,7 @@ #define STM32MP_BL32_BASE (STM32MP_BL32_DTB_BASE + \ STM32MP_BL32_DTB_SIZE) + #if defined(IMAGE_BL2) #define STM32MP_DTB_SIZE STM32MP_BL2_DTB_SIZE #define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE @@ -41,6 +46,9 @@ STM32MP_OPTEE_BASE) #endif +#define STM32MP_FW_CONFIG_BASE (STM32MP_SYSRAM_BASE + \ + STM32MP_SYSRAM_SIZE - \ + PAGE_SIZE) #define STM32MP_HW_CONFIG_BASE (STM32MP_BL33_BASE + \ STM32MP_BL33_MAX_SIZE) diff --git a/plat/st/stm32mp1/stm32mp1_stm32image_def.h b/plat/st/stm32mp1/stm32mp1_stm32image_def.h index 8bae56ae5..8efa342c1 100644 --- a/plat/st/stm32mp1/stm32mp1_stm32image_def.h +++ b/plat/st/stm32mp1/stm32mp1_stm32image_def.h @@ -7,6 +7,14 @@ #ifndef STM32MP1_STM32IMAGE_DEF_H #define STM32MP1_STM32IMAGE_DEF_H +#ifdef AARCH32_SP_OPTEE +#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */ +#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */ +#else +#define STM32MP_DDR_S_SIZE U(0) +#define STM32MP_DDR_SHMEM_SIZE U(0) +#endif + #define STM32MP_BL2_SIZE U(0x0001C000) /* 112 KB for BL2 */ #define STM32MP_DTB_SIZE U(0x00006000) /* 24 KB for DTB */ -- cgit v1.2.3 From d5a84eeaac2c8ce14d3f2662dc9523b4abf41516 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 13 Jul 2021 18:07:41 +0200 Subject: feat(plat/st): manage io_policies with FCONF Introduced IO policies management through the trusted boot firmware config device tree for UUID references. Change-Id: Ibeeabede51b0514ebba26dbbdae587363b2aa0a7 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- plat/st/common/bl2_io_storage.c | 117 ++----------------------- plat/st/common/include/stm32mp_fconf_getter.h | 29 ++++++ plat/st/common/include/stm32mp_io_storage.h | 23 +++++ plat/st/common/stm32mp_fconf_io.c | 121 ++++++++++++++++++++++++++ plat/st/stm32mp1/bl2_plat_setup.c | 4 + plat/st/stm32mp1/platform.mk | 2 + 6 files changed, 185 insertions(+), 111 deletions(-) create mode 100644 plat/st/common/include/stm32mp_fconf_getter.h create mode 100644 plat/st/common/include/stm32mp_io_storage.h create mode 100644 plat/st/common/stm32mp_fconf_io.c diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 817f44972..7e76083b3 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -24,12 +24,14 @@ #include #include #include +#include #include #include #include #include #include +#include /* IO devices */ uintptr_t fip_dev_handle; @@ -39,10 +41,6 @@ static const io_dev_connector_t *fip_dev_con; #if STM32MP_SDMMC || STM32MP_EMMC static struct mmc_device_info mmc_info; -static io_block_spec_t gpt_block_spec = { - .offset = 0U, - .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ -}; static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); @@ -97,118 +95,17 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif -static const io_uuid_spec_t fw_config_uuid_spec = { - .uuid = UUID_FW_CONFIG, -}; - -static const io_uuid_spec_t bl33_partition_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33 -}; - -static const io_uuid_spec_t tos_fw_config_uuid_spec = { - .uuid = UUID_TOS_FW_CONFIG, -}; - -static const io_uuid_spec_t hw_config_uuid_spec = { - .uuid = UUID_HW_CONFIG, -}; - -#ifdef AARCH32_SP_OPTEE -static const io_uuid_spec_t optee_header_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32 -}; - -static const io_uuid_spec_t optee_core_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1 -}; - -static const io_uuid_spec_t optee_paged_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2 -}; -#else -static const io_uuid_spec_t bl32_partition_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32 -}; -#endif - -static io_block_spec_t image_block_spec = { +io_block_spec_t image_block_spec = { .offset = 0U, .length = 0U, }; -static int open_fip(const uintptr_t spec); -static int open_storage(const uintptr_t spec); - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&image_block_spec, - .check = open_storage - }, -#ifdef AARCH32_SP_OPTEE - [BL32_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_header_partition_spec, - .check = open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_core_partition_spec, - .check = open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&optee_paged_partition_spec, - .check = open_fip - }, -#else - [BL32_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&bl32_partition_spec, - .check = open_fip - }, -#endif - [BL33_IMAGE_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&bl33_partition_spec, - .check = open_fip - }, - [FW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&fw_config_uuid_spec, - .check = open_fip - }, - [TOS_FW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&tos_fw_config_uuid_spec, - .check = open_fip - }, - [HW_CONFIG_ID] = { - .dev_handle = &fip_dev_handle, - .image_spec = (uintptr_t)&hw_config_uuid_spec, - .check = open_fip - }, -#if STM32MP_SDMMC || STM32MP_EMMC - [GPT_IMAGE_ID] = { - .dev_handle = &storage_dev_handle, - .image_spec = (uintptr_t)&gpt_block_spec, - .check = open_storage - }, -#endif -}; - -static int open_fip(const uintptr_t spec) +int open_fip(const uintptr_t spec) { return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); } -static int open_storage(const uintptr_t spec) +int open_storage(const uintptr_t spec) { return io_dev_init(storage_dev_handle, 0); } @@ -478,9 +375,7 @@ int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, int rc; const struct plat_io_policy *policy; - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; + policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); rc = policy->check(policy->image_spec); if (rc == 0) { *image_spec = policy->image_spec; diff --git a/plat/st/common/include/stm32mp_fconf_getter.h b/plat/st/common/include/stm32mp_fconf_getter.h new file mode 100644 index 000000000..3a8bb11a4 --- /dev/null +++ b/plat/st/common/include/stm32mp_fconf_getter.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP_FCONF_GETTER +#define STM32MP_FCONF_GETTER + +#include + +#include + +/* IO policies */ +#define stm32mp__io_policies_getter(id) __extension__ ({ \ + assert((id) < MAX_NUMBER_IDS); \ + &policies[id]; \ +}) + +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +extern struct plat_io_policy policies[]; +int fconf_populate_stm32mp_io_policies(uintptr_t config); + +#endif /* STM32MP_FCONF_GETTER */ diff --git a/plat/st/common/include/stm32mp_io_storage.h b/plat/st/common/include/stm32mp_io_storage.h new file mode 100644 index 000000000..989c890d4 --- /dev/null +++ b/plat/st/common/include/stm32mp_io_storage.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef STM32MP_IO_STORAGE_H +#define STM32MP_IO_STORAGE_H + +#include + +#include + +/* IO devices handle */ +extern uintptr_t storage_dev_handle; +extern uintptr_t fip_dev_handle; + +extern io_block_spec_t image_block_spec; + +/* Function declarations */ +int open_fip(const uintptr_t spec); +int open_storage(const uintptr_t spec); + +#endif /* STM32MP_IO_STORAGE_H */ diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c new file mode 100644 index 000000000..aa8cd5441 --- /dev/null +++ b/plat/st/common/stm32mp_fconf_io.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if STM32MP_SDMMC || STM32MP_EMMC +static io_block_spec_t gpt_block_spec = { + .offset = 0U, + .length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */ +}; +#endif + +/* By default, STM32 platforms load images from the FIP */ +struct plat_io_policy policies[MAX_NUMBER_IDS] = { + [FIP_IMAGE_ID] = { + &storage_dev_handle, + (uintptr_t)&image_block_spec, + open_storage + }, +#if STM32MP_SDMMC || STM32MP_EMMC + [GPT_IMAGE_ID] = { + &storage_dev_handle, + (uintptr_t)&gpt_block_spec, + open_storage + }, +#endif +}; + +#define FCONF_ST_IO_UUID_NUMBER U(8) + +static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER]; +static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids); + +struct policies_load_info { + unsigned int image_id; + const char *name; +}; + +/* image id to property name table */ +static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = { + {FW_CONFIG_ID, "fw_cfg_uuid"}, + {BL32_IMAGE_ID, "bl32_uuid"}, + {BL32_EXTRA1_IMAGE_ID, "bl32_extra1_uuid"}, + {BL32_EXTRA2_IMAGE_ID, "bl32_extra2_uuid"}, + {BL33_IMAGE_ID, "bl33_uuid"}, + {HW_CONFIG_ID, "hw_cfg_uuid"}, + {TOS_FW_CONFIG_ID, "tos_fw_cfg_uuid"}, + {NT_FW_CONFIG_ID, "nt_fw_cfg_uuid"}, +}; + +int fconf_populate_stm32mp_io_policies(uintptr_t config) +{ + int node; + unsigned int i; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + + /* Assert the node offset point to "st,io-fip-handle" compatible property */ + const char *compatible_str = "st,io-fip-handle"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + /* Locate the uuid cells and read the value for all the load info uuid */ + for (i = 0U; i < FCONF_ST_IO_UUID_NUMBER; i++) { + union uuid_helper_t uuid_helper; + io_uuid_spec_t *uuid_ptr; + int err; + + uuid_ptr = pool_alloc(&fconf_stm32mp_uuids_pool); + err = fdtw_read_uuid(dtb, node, load_info[i].name, 16, + (uint8_t *)&uuid_helper); + if (err < 0) { + WARN("FCONF: Read cell failed for %s\n", load_info[i].name); + return err; + } + + VERBOSE("FCONF: stm32mp-io_policies.%s cell found with value = " + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", + load_info[i].name, + uuid_helper.uuid_struct.time_low[0], uuid_helper.uuid_struct.time_low[1], + uuid_helper.uuid_struct.time_low[2], uuid_helper.uuid_struct.time_low[3], + uuid_helper.uuid_struct.time_mid[0], uuid_helper.uuid_struct.time_mid[1], + uuid_helper.uuid_struct.time_hi_and_version[0], + uuid_helper.uuid_struct.time_hi_and_version[1], + uuid_helper.uuid_struct.clock_seq_hi_and_reserved, + uuid_helper.uuid_struct.clock_seq_low, + uuid_helper.uuid_struct.node[0], uuid_helper.uuid_struct.node[1], + uuid_helper.uuid_struct.node[2], uuid_helper.uuid_struct.node[3], + uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5]); + + uuid_ptr->uuid = uuid_helper.uuid_struct; + policies[load_info[i].image_id].image_spec = (uintptr_t)uuid_ptr; + policies[load_info[i].image_id].dev_handle = &fip_dev_handle; + policies[load_info[i].image_id].check = open_fip; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, stm32mp_io, fconf_populate_stm32mp_io_policies); diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 9053a2541..e87c529b7 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -330,6 +330,10 @@ skip_console_init: print_reset_reason(); +#if !STM32MP_USE_STM32IMAGE + fconf_populate("TB_FW", STM32MP_DTB_BASE); +#endif /* !STM32MP_USE_STM32IMAGE */ + stm32mp_io_setup(); } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index d415a1ecc..891cfa4b6 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -157,6 +157,7 @@ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ include lib/libfdt/libfdt.mk PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ + common/uuid.c \ plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c @@ -196,6 +197,7 @@ BL2_SOURCES += drivers/io/io_fip.c \ lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ + plat/st/common/stm32mp_fconf_io.c \ plat/st/stm32mp1/plat_bl2_mem_params_desc.c else BL2_SOURCES += drivers/io/io_dummy.c \ -- cgit v1.2.3 From 3cc5155c8485fa7d991c145ec2a15eced1447824 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 5 Jul 2021 14:07:29 +0200 Subject: refactor(plat/st): use TZC400 bindings This avoids duplicate define of TZC_REGION_NSEC_ALL_ACCESS_RDWR. And remove the previous TZC400 definitions from stm32mp1_def.h. Change-Id: I6c72c2a18731f69d855fbce8ce822a21da9364fa Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_def.h | 12 ------------ plat/st/stm32mp1/stm32mp1_security.c | 14 +------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index f14bf8c4c..0d3666074 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -309,18 +309,6 @@ enum ddr_type { ******************************************************************************/ #define STM32MP1_TZC_BASE U(0x5C006000) -#define STM32MP1_TZC_A7_ID U(0) -#define STM32MP1_TZC_M4_ID U(1) -#define STM32MP1_TZC_LCD_ID U(3) -#define STM32MP1_TZC_GPU_ID U(4) -#define STM32MP1_TZC_MDMA_ID U(5) -#define STM32MP1_TZC_DMA_ID U(6) -#define STM32MP1_TZC_USB_HOST_ID U(7) -#define STM32MP1_TZC_USB_OTG_ID U(8) -#define STM32MP1_TZC_SDMMC_ID U(9) -#define STM32MP1_TZC_ETH_ID U(10) -#define STM32MP1_TZC_DAP_ID U(15) - #define STM32MP1_FILTER_BIT_ALL (TZC_400_REGION_ATTR_FILTER_BIT(0) | \ TZC_400_REGION_ATTR_FILTER_BIT(1)) diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c index 2ee5f4a85..19ef4f0ae 100644 --- a/plat/st/stm32mp1/stm32mp1_security.c +++ b/plat/st/stm32mp1/stm32mp1_security.c @@ -12,21 +12,9 @@ #include #include #include +#include #include -#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \ - TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID) - static unsigned int region_nb; static void init_tzc400_begin(unsigned int region0_attr) -- cgit v1.2.3 From 86b43c58a4105c8cef13d860dd73fa9bd560526a Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 2 Jul 2021 11:53:18 +0200 Subject: feat(fdts): add firewall regions into STM32MP1 DT Add the corresponding firewall memory regions into fw-config device tree. Change-Id: Ie39b0339f3c42b3dd756354138a872500c64f84c Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- fdts/stm32mp15-fw-config.dtsi | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/fdts/stm32mp15-fw-config.dtsi b/fdts/stm32mp15-fw-config.dtsi index 4f2841f8e..8aece289a 100644 --- a/fdts/stm32mp15-fw-config.dtsi +++ b/fdts/stm32mp15-fw-config.dtsi @@ -4,9 +4,27 @@ */ #include +#include #include +#ifndef DDR_SIZE +#error "DDR_SIZE is not defined" +#endif + +#define DDR_NS_BASE STM32MP_DDR_BASE +#ifdef AARCH32_SP_OPTEE +/* OP-TEE reserved shared memory: located at DDR top */ +#define DDR_SHARE_SIZE STM32MP_DDR_SHMEM_SIZE +#define DDR_SHARE_BASE (STM32MP_DDR_BASE + (DDR_SIZE - DDR_SHARE_SIZE)) +/* OP-TEE secure memory: located right below OP-TEE reserved shared memory */ +#define DDR_SEC_SIZE STM32MP_DDR_S_SIZE +#define DDR_SEC_BASE (DDR_SHARE_BASE - DDR_SEC_SIZE) +#define DDR_NS_SIZE (DDR_SEC_BASE - DDR_NS_BASE) +#else /* !AARCH32_SP_OPTEE */ +#define DDR_NS_SIZE DDR_SIZE +#endif /* AARCH32_SP_OPTEE */ + /dts-v1/; / { @@ -43,6 +61,20 @@ max-size = ; id = ; }; +#endif + }; + + st-mem-firewall { + compatible = "st,mem-firewall"; +#ifdef AARCH32_SP_OPTEE + memory-ranges = < + DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR + DDR_SEC_BASE DDR_SEC_SIZE TZC_REGION_S_RDWR 0 + DDR_SHARE_BASE DDR_SHARE_SIZE TZC_REGION_S_NONE + TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID)>; +#else + memory-ranges = < + DDR_NS_BASE DDR_NS_SIZE TZC_REGION_S_NONE TZC_REGION_NSEC_ALL_ACCESS_RDWR>; #endif }; }; -- cgit v1.2.3 From 34a87d74d9fbbe8037431ea5101110a9f1cf30e1 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Tue, 17 Aug 2021 17:57:10 +0100 Subject: feat(tc): populate HW_CONFIG in BL31 BL2 passes FW_CONFIG to BL31 which contains information about different DTBs present. BL31 then uses FW_CONFIG to get the base address of HW_CONFIG and populate fconf. Signed-off-by: Usama Arif Change-Id: I0b4fc83e6e0a0b9401f692516654eb9a3b037616 --- plat/arm/board/tc/fdts/tc_fw_config.dts | 4 +-- plat/arm/board/tc/include/platform_def.h | 10 ++++++- plat/arm/board/tc/platform.mk | 4 +++ plat/arm/board/tc/tc_bl2_setup.c | 47 ++++++++++++++++++++++++++++++++ plat/arm/board/tc/tc_bl31_setup.c | 20 +++++++++++++- plat/arm/board/tc/tc_plat.c | 3 +- 6 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 plat/arm/board/tc/tc_bl2_setup.c diff --git a/plat/arm/board/tc/fdts/tc_fw_config.dts b/plat/arm/board/tc/fdts/tc_fw_config.dts index 4b6abd4d1..a84c7f85f 100644 --- a/plat/arm/board/tc/fdts/tc_fw_config.dts +++ b/plat/arm/board/tc/fdts/tc_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,7 +26,7 @@ hw-config { load-address = <0x0 0x83000000>; - max-size = <0x01000000>; + max-size = <0x8000>; id = ; }; }; diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h index c8edd2fbb..ccabced9e 100644 --- a/plat/arm/board/tc/include/platform_def.h +++ b/plat/arm/board/tc/include/platform_def.h @@ -55,6 +55,14 @@ TC_TZC_DRAM1_BASE, \ TC_TZC_DRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_SECURE) + +#define PLAT_HW_CONFIG_DTB_BASE ULL(0x83000000) +#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) + +#define PLAT_DTB_DRAM_NS MAP_REGION_FLAT( \ + PLAT_HW_CONFIG_DTB_BASE, \ + PLAT_HW_CONFIG_DTB_SIZE, \ + MT_MEMORY | MT_RO | MT_NS) /* * Max size of SPMC is 2MB for tc. With SPMD enabled this value corresponds to * max size of BL32 image. @@ -122,7 +130,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE 0x3B000 +#define PLAT_ARM_MAX_BL31_SIZE 0x3F000 /* * Size of cacheable stacks diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index 8db764ca1..d0629fd51 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -77,6 +77,7 @@ BL1_SOURCES += ${INTERCONNECT_SOURCES} \ BL2_SOURCES += ${TC_BASE}/tc_security.c \ ${TC_BASE}/tc_err.c \ ${TC_BASE}/tc_trusted_boot.c \ + ${TC_BASE}/tc_bl2_setup.c \ lib/utils/mem_region.c \ drivers/arm/tzc/tzc400.c \ plat/arm/common/arm_tzc400.c \ @@ -87,6 +88,9 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ ${ENT_GIC_SOURCES} \ ${TC_BASE}/tc_bl31_setup.c \ ${TC_BASE}/tc_topology.c \ + common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c diff --git a/plat/arm/board/tc/tc_bl2_setup.c b/plat/arm/board/tc/tc_bl2_setup.c new file mode 100644 index 000000000..74ef569eb --- /dev/null +++ b/plat/arm/board/tc/tc_bl2_setup.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + +#include + +/******************************************************************************* + * This function returns the list of executable images + ******************************************************************************/ +struct bl_params *plat_get_next_bl_params(void) +{ + struct bl_params *arm_bl_params = arm_get_next_bl_params(); + + const struct dyn_cfg_dtb_info_t *fw_config_info; + bl_mem_params_node_t *param_node; + uintptr_t fw_config_base = 0U; + entry_point_info_t *ep_info; + + /* Get BL31 image node */ + param_node = get_bl_mem_params_node(BL31_IMAGE_ID); + assert(param_node != NULL); + + /* Get fw_config load address */ + fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); + assert(fw_config_info != NULL); + + fw_config_base = fw_config_info->config_addr; + assert(fw_config_base != 0U); + + /* + * Get the entry point info of BL31 image and override + * arg1 of entry point info with fw_config base address + */ + ep_info = ¶m_node->ep_info; + ep_info->args.arg1 = (uint32_t)fw_config_base; + + return arm_bl_params; +} diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c index ecec26c05..0523ef8f2 100644 --- a/plat/arm/board/tc/tc_bl31_setup.c +++ b/plat/arm/board/tc/tc_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -42,6 +44,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); + + /* Fill the properties struct with the info from the config dtb */ + fconf_populate("FW_CONFIG", arg1); } void tc_bl31_common_platform_setup(void) @@ -53,3 +58,16 @@ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) { return css_scmi_override_pm_ops(ops); } + +void __init bl31_plat_arch_setup(void) +{ + arm_bl31_plat_arch_setup(); + + /* HW_CONFIG was also loaded by BL2 */ + const struct dyn_cfg_dtb_info_t *hw_config_info; + + hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID); + assert(hw_config_info != NULL); + + fconf_populate("HW_CONFIG", hw_config_info->config_addr); +} diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c index 3863a0a13..a9668e117 100644 --- a/plat/arm/board/tc/tc_plat.c +++ b/plat/arm/board/tc/tc_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,6 +63,7 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, V2M_MAP_IOFPGA, TC_MAP_DEVICE, + PLAT_DTB_DRAM_NS, #if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif -- cgit v1.2.3 From 10198eab3aa7b0eeba10d9667197816b052ba3e4 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Fri, 20 Aug 2021 20:53:34 +0100 Subject: feat(tc): Enable SVE for both secure and non-secure world Signed-off-by: Usama Arif Change-Id: I0ae8a6ea3245373a17af76c9b7dc3f38f3711091 --- plat/arm/board/tc/platform.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index d0629fd51..7ebf6391d 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -31,6 +31,9 @@ GIC_ENABLE_V4_EXTN := 1 # GIC-600 configuration GICV3_SUPPORT_GIC600 := 1 +# Enable SVE +ENABLE_SVE_FOR_NS := 1 +ENABLE_SVE_FOR_SWD := 1 # Include GICv3 driver files include drivers/arm/gic/v3/gicv3.mk -- cgit v1.2.3 From cc35a3771d28a96906f8d0f393ff664924a2d4dc Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Tue, 24 Aug 2021 13:52:55 +0530 Subject: fix(plat/qti/sc7180): qti smc addition Adding QTI SIP SMC CALL to detect qti platform supporting ARM 64 SMC calls or not. Signed-off-by: Saurabh Gorecha Change-Id: I3231325a6ffe5aa69856dd25ac2c0a2004484e4b --- plat/qti/common/src/qti_syscall.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/plat/qti/common/src/qti_syscall.c b/plat/qti/common/src/qti_syscall.c index a7601b657..d8e5be9f6 100644 --- a/plat/qti/common/src/qti_syscall.c +++ b/plat/qti/common/src/qti_syscall.c @@ -21,6 +21,7 @@ #include #include #include + /* * SIP service - SMC function IDs for SiP Service queries * @@ -29,7 +30,7 @@ #define QTI_SIP_SVC_UID_ID U(0x0200ff01) /* 0x8200ff02 is reserved*/ #define QTI_SIP_SVC_VERSION_ID U(0x0200ff03) - +#define QTI_SIP_SVC_AVAILABLE_ID U(0x02000601) /* * Syscall's to allow Non Secure world accessing peripheral/IO memory * those are secure/proteced BUT not required to be secure. @@ -83,6 +84,22 @@ static bool qti_is_secure_io_access_allowed(u_register_t addr) return false; } +static bool qti_check_syscall_availability(u_register_t smc_fid) +{ + switch (smc_fid) { + case QTI_SIP_SVC_CALL_COUNT_ID: + case QTI_SIP_SVC_UID_ID: + case QTI_SIP_SVC_VERSION_ID: + case QTI_SIP_SVC_AVAILABLE_ID: + case QTI_SIP_SVC_SECURE_IO_READ_ID: + case QTI_SIP_SVC_SECURE_IO_WRITE_ID: + case QTI_SIP_SVC_MEM_ASSIGN_ID: + return true; + default: + return false; + } +} + bool qti_mem_assign_validate_param(memprot_info_t *mem_info, u_register_t u_num_mappings, uint32_t *source_vm_list, @@ -315,6 +332,18 @@ static uintptr_t qti_sip_handler(uint32_t smc_fid, QTI_SIP_SVC_VERSION_MINOR); break; } + case QTI_SIP_SVC_AVAILABLE_ID: + { + if (x1 != 1) { + SMC_RET1(handle, QTI_SIP_INVALID_PARAM); + } + if (qti_check_syscall_availability(x2) == true) { + SMC_RET2(handle, QTI_SIP_SUCCESS, 1); + } else { + SMC_RET2(handle, QTI_SIP_SUCCESS, 0); + } + break; + } case QTI_SIP_SVC_SECURE_IO_READ_ID: { if ((x1 == QTI_SIP_SVC_SECURE_IO_READ_PARAM_ID) && -- cgit v1.2.3 From 6c3d92e33fe4e6964576e78df23351085c4c7291 Mon Sep 17 00:00:00 2001 From: Jayanth Dodderi Chidanand Date: Tue, 31 Aug 2021 12:27:48 +0100 Subject: docs(contribution-guidelines): add coverity build configuration section Added a sub-section in the "Processes and Policies" chapter under Contributor's guide on how to add new build configurations when new source files are added to the TF-A repository. This will help the patch contributor to update their files to get analysed by Coverity Scan. Signed-off-by: Jayanth Dodderi Chidanand Change-Id: I71f410a061028f89bd0e984e48e61e5935616d71 --- docs/process/contributing.rst | 63 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index c91903a89..a0d068322 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -209,6 +209,65 @@ Submitting Changes revert your patches and ask you to resubmit a reworked version of them or they may ask you to provide a fix-up patch. +Add Build Configurations +------------------------ + +- TF-A uses Jenkins tool for Continuous Integration and testing activities. + Various CI Jobs are deployed which run tests on every patch before being + merged. So each of your patches go through a series of checks before they + get merged on to the master branch. + +- ``Coverity Scan analysis`` is one of the tests we perform on our source code + at regular intervals. We maintain a build script ``tf-cov-make`` which contains the + build configurations of various platforms in order to cover the entire source + code being analysed by Coverity. + +- When you submit your patches for review containing new source files, please + ensure to include them for the ``Coverity Scan analysis`` by adding the + respective build configurations in the ``tf-cov-make`` build script. + +- In this section you find the details on how to append your new build + configurations for Coverity Scan analysis: + +#. We maintain a separate repository named `tf-a-ci-scripts repository`_ + for placing all the test scripts which will be executed by the CI Jobs. + +#. In this repository, ``tf-cov-make`` script is located at + ``tf-a-ci-scripts/script/tf-coverity/tf-cov-make`` + +#. Edit `tf-cov-make`_ script by appending all the possible build configurations with + the specific ``build-flags`` relevant to your platform, so that newly added + source files get built and analysed by Coverity. + +#. For better understanding follow the below specified examples listed in the + ``tf-cov-make`` script. + +.. code:: c + + Example 1: + #Intel + make PLAT=stratix10 $(common_flags) all + make PLAT=agilex $(common_flags) all + +- In the above example there are two different SoCs ``stratix`` and ``agilex`` + under the Intel platform and the build configurations has been added suitably + to include most of their source files. + +.. code:: c + + Example 2: + #Hikey + make PLAT=hikey $(common_flags) ${TBB_OPTIONS} ENABLE_PMF=1 all + make PLAT=hikey960 $(common_flags) ${TBB_OPTIONS} all + make PLAT=poplar $(common_flags) all + +- In this case for ``Hikey`` boards additional ``build-flags`` has been included + along with the ``commom_flags`` to cover most of the files relevant to it. + +- Similar to this you can still find many other different build configurations + of various other platforms listed in the ``tf-cov-make`` script. Kindly refer + them and append your build configurations respectively. + Binary Components ----------------- @@ -228,7 +287,7 @@ Binary Components -------------- -*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.* .. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0 .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org @@ -243,3 +302,5 @@ Binary Components .. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries .. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst .. _TF-A mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a +.. _tf-a-ci-scripts repository: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/ +.. _tf-cov-make: https://git.trustedfirmware.org/ci/tf-a-ci-scripts.git/tree/script/tf-coverity/tf-cov-make -- cgit v1.2.3 From ce7ef9d146ce5ca6b9be5ef049377b3817d53d10 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Sun, 27 Sep 2020 20:48:30 +0200 Subject: feat(tzc400): update filters by region Add a new function that allows to enable or disabled filters on configured regions dynamically. This will avoid the need to reconfigure the entire attribute and just manage to enable/disable filters. Change-Id: If0937ca755bec6c45d3649718147108459682fff Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/arm/tzc/tzc400.c | 10 ++++++++++ drivers/arm/tzc/tzc_common_private.h | 23 ++++++++++++++++++++++- include/drivers/arm/tzc400.h | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index 9fc1578a1..f1dacbbbd 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -68,6 +68,7 @@ DEFINE_TZC_COMMON_WRITE_REGION_BASE(400, 400) DEFINE_TZC_COMMON_WRITE_REGION_TOP(400, 400) DEFINE_TZC_COMMON_WRITE_REGION_ATTRIBUTES(400, 400) DEFINE_TZC_COMMON_WRITE_REGION_ID_ACCESS(400, 400) +DEFINE_TZC_COMMON_UPDATE_FILTERS(400, 400) DEFINE_TZC_COMMON_CONFIGURE_REGION0(400) DEFINE_TZC_COMMON_CONFIGURE_REGION(400) @@ -271,6 +272,15 @@ void tzc400_configure_region(unsigned int filters, sec_attr, nsaid_permissions); } +void tzc400_update_filters(unsigned int region, unsigned int filters) +{ + /* Do range checks on filters and regions. */ + assert(((filters >> tzc400.num_filters) == 0U) && + (region < tzc400.num_regions)); + + _tzc400_update_filters(tzc400.base, region, tzc400.num_filters, filters); +} + void tzc400_enable_filters(void) { unsigned int state; diff --git a/drivers/arm/tzc/tzc_common_private.h b/drivers/arm/tzc/tzc_common_private.h index 1d99077ad..2090944a7 100644 --- a/drivers/arm/tzc/tzc_common_private.h +++ b/drivers/arm/tzc/tzc_common_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -89,6 +89,27 @@ val); \ } +/* + * It is used to modify the filters status for a defined region. + */ +#define DEFINE_TZC_COMMON_UPDATE_FILTERS(fn_name, macro_name) \ + static inline void _tzc##fn_name##_update_filters( \ + uintptr_t base, \ + unsigned int region_no, \ + unsigned int nbfilters, \ + unsigned int filters) \ + { \ + uint32_t filters_mask = GENMASK(nbfilters - 1U, 0); \ + \ + mmio_clrsetbits_32(base + \ + TZC_REGION_OFFSET( \ + TZC_##macro_name##_REGION_SIZE, \ + region_no) + \ + TZC_##macro_name##_REGION_ATTR_0_OFFSET, \ + filters_mask << TZC_REGION_ATTR_F_EN_SHIFT, \ + filters << TZC_REGION_ATTR_F_EN_SHIFT); \ + } + /* * It is used to program region 0 ATTRIBUTES and ACCESS register. */ diff --git a/include/drivers/arm/tzc400.h b/include/drivers/arm/tzc400.h index 5f8a48f57..765c130eb 100644 --- a/include/drivers/arm/tzc400.h +++ b/include/drivers/arm/tzc400.h @@ -109,6 +109,7 @@ void tzc400_configure_region(unsigned int filters, unsigned long long region_top, unsigned int sec_attr, unsigned int nsaid_permissions); +void tzc400_update_filters(unsigned int region, unsigned int filters); void tzc400_set_action(unsigned int action); void tzc400_enable_filters(void); void tzc400_disable_filters(void); -- cgit v1.2.3 From 4584e01dc643665038004f6c8a4f8bd64e14dacb Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Sun, 27 Sep 2020 21:13:53 +0200 Subject: feat(plat/st): add a new DDR firewall management Based on FCONF framework, define DDR firewall regions from firmware config file instead of static defines. Change-Id: I471e15410ca286d9079a86e3dc3474f66d37b5ab Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- plat/st/stm32mp1/include/stm32mp1_private.h | 4 +- plat/st/stm32mp1/platform.mk | 7 +- plat/st/stm32mp1/stm32mp1_fconf_firewall.c | 123 ++++++++++++++++++++++++++++ plat/st/stm32mp1/stm32mp1_private.c | 2 + 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 plat/st/stm32mp1/stm32mp1_fconf_firewall.c diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h index b6cb91efa..729d2336b 100644 --- a/plat/st/stm32mp1/include/stm32mp1_private.h +++ b/plat/st/stm32mp1/include/stm32mp1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,7 +21,9 @@ void stm32mp1_syscfg_init(void); void stm32mp1_syscfg_enable_io_compensation(void); void stm32mp1_syscfg_disable_io_compensation(void); +#if STM32MP_USE_STM32IMAGE uint32_t stm32mp_get_ddr_ns_size(void); +#endif /* STM32MP_USE_STM32IMAGE */ void stm32mp1_init_scmi_server(void); #endif /* STM32MP1_PRIVATE_H */ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 891cfa4b6..1c2c9f0a9 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -189,7 +189,6 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ plat/st/stm32mp1/stm32mp1_context.c \ plat/st/stm32mp1/stm32mp1_dbgmcu.c \ plat/st/stm32mp1/stm32mp1_helper.S \ - plat/st/stm32mp1/stm32mp1_security.c \ plat/st/stm32mp1/stm32mp1_syscfg.c ifneq (${STM32MP_USE_STM32IMAGE},1) @@ -198,12 +197,14 @@ BL2_SOURCES += drivers/io/io_fip.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ plat/st/common/stm32mp_fconf_io.c \ - plat/st/stm32mp1/plat_bl2_mem_params_desc.c + plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ + plat/st/stm32mp1/stm32mp1_fconf_firewall.c else BL2_SOURCES += drivers/io/io_dummy.c \ drivers/st/io/io_stm32image.c \ plat/st/common/bl2_stm32_io_storage.c \ - plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c + plat/st/stm32mp1/plat_bl2_stm32_mem_params_desc.c \ + plat/st/stm32mp1/stm32mp1_security.c endif BL2_SOURCES += drivers/io/io_block.c \ diff --git a/plat/st/stm32mp1/stm32mp1_fconf_firewall.c b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c new file mode 100644 index 000000000..caf9ff12b --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_fconf_firewall.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define STM32MP_REGION_PARAMS 4 +#define STM32MP_MAX_REGIONS 8 +#define FORCE_SEC_REGION BIT(31) + +static uint32_t nb_regions; + +struct dt_id_attr { + fdt32_t id_attr[STM32MP_MAX_REGIONS]; +}; + +void stm32mp1_arch_security_setup(void) +{ + stm32mp_clk_enable(TZC1); + stm32mp_clk_enable(TZC2); + + tzc400_init(STM32MP1_TZC_BASE); + tzc400_disable_filters(); + + /* + * Region 0 set to cover all DRAM at 0xC000_0000 + * Only secure access is granted in read/write. + */ + tzc400_configure_region0(TZC_REGION_S_RDWR, 0); + + tzc400_set_action(TZC_ACTION_ERR); + tzc400_enable_filters(); +} + +void stm32mp1_security_setup(void) +{ + uint8_t i; + + assert(nb_regions > 0U); + + tzc400_init(STM32MP1_TZC_BASE); + tzc400_disable_filters(); + + /* + * Region 0 set to cover all DRAM at 0xC000_0000 + * No access is allowed. + */ + tzc400_configure_region0(TZC_REGION_S_NONE, 0); + + for (i = 1U; i <= nb_regions; i++) { + tzc400_update_filters(i, STM32MP1_FILTER_BIT_ALL); + } + + tzc400_set_action(TZC_ACTION_INT); + tzc400_enable_filters(); +} + +static int fconf_populate_stm32mp1_firewall(uintptr_t config) +{ + int node, len; + unsigned int i; + const struct dt_id_attr *conf_list; + const void *dtb = (const void *)config; + + /* Assert the node offset point to "st,mem-firewall" compatible property */ + const char *compatible_str = "st,mem-firewall"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str); + return node; + } + + conf_list = (const struct dt_id_attr *)fdt_getprop(dtb, node, "memory-ranges", &len); + if (conf_list == NULL) { + WARN("FCONF: Read cell failed for %s\n", "memory-ranges"); + return -1; + } + + /* Locate the memory cells and read all values */ + for (i = 0U; i < (unsigned int)(len / (sizeof(uint32_t) * STM32MP_REGION_PARAMS)); i++) { + uint32_t base; + uint32_t size; + uint32_t sec_attr; + uint32_t nsaid; + + base = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS]); + size = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 1]); + sec_attr = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 2]); + nsaid = fdt32_to_cpu(conf_list->id_attr[i * STM32MP_REGION_PARAMS + 3]); + + VERBOSE("FCONF: stm32mp1-firewall cell found with value = 0x%x 0x%x 0x%x 0x%x\n", + base, size, sec_attr, nsaid); + + nb_regions++; + + /* Configure region but keep disabled for secure access for BL2 load */ + tzc400_configure_region(0U, nb_regions, (unsigned long long)base, + (unsigned long long)base + size - 1ULL, sec_attr, nsaid); + } + + /* Force flush as the value will be used cache off */ + flush_dcache_range((uintptr_t)&nb_regions, sizeof(uint32_t)); + + return 0; +} + +FCONF_REGISTER_POPULATOR(FW_CONFIG, stm32mp1_firewall, fconf_populate_stm32mp1_firewall); diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 1af0075f2..e4065c1c9 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -452,6 +452,7 @@ uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags) } #endif +#if STM32MP_USE_STM32IMAGE /* Get the non-secure DDR size */ uint32_t stm32mp_get_ddr_ns_size(void) { @@ -472,3 +473,4 @@ uint32_t stm32mp_get_ddr_ns_size(void) return ddr_ns_size; } +#endif /* STM32MP_USE_STM32IMAGE */ -- cgit v1.2.3 From 07f81627ab38f488b3780023c5fd9633ce9209c8 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 12 Feb 2021 18:04:23 +0100 Subject: docs(stm32mp1): update doc for FIP/FCONF Describe the boot using FIP, and how to compile it. The STM32IMAGE boot chain is still available but it is not recommended. Update the build command lines, for FIP. The memory mapping is also updated. Change-Id: I2b1e0df5500b6213d33dc558b0e0da38340a4d79 Signed-off-by: Yann Gautier --- docs/plat/stm32mp1.rst | 140 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 14 deletions(-) diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst index 0ef292347..17f7a8618 100644 --- a/docs/plat/stm32mp1.rst +++ b/docs/plat/stm32mp1.rst @@ -37,6 +37,17 @@ The TF-A image must be properly formatted with a STM32 header structure for ROM code is able to load this image. Tool stm32image can be used to prepend this header to the generated TF-A binary. +Boot with FIP +~~~~~~~~~~~~~ +The use of FIP is now the recommended way to boot STM32MP1 platform. +Only BL2 (with STM32 header) is loaded by ROM code. The other binaries are +inside the FIP binary: BL32 (SP_min or OP-TEE), U-Boot and their respective +device tree blobs. + +STM32IMAGE bootchain +~~~~~~~~~~~~~~~~~~~~ +Although still supported, this way of booting is not recommended. +Pease use FIP instead. At compilation step, BL2, BL32 and DTB file are linked together in a single binary. The stm32image tool is also generated and the header is added to TF-A binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32. @@ -55,15 +66,17 @@ Memory mapping | ... | | | 0x2FFC0000 +-----------------+ \ - | | | + | BL32 DTB | | + 0x2FFC5000 +-----------------+ | + | BL32 | | + 0x2FFDF000 +-----------------+ | | ... | | - | | | - 0x2FFD8000 +-----------------+ | - | TF-A DTB | | Embedded SRAM - 0x2FFDC000 +-----------------+ | + 0x2FFE3000 +-----------------+ | + | BL2 DTB | | Embedded SRAM + 0x2FFEA000 +-----------------+ | | BL2 | | - 0x2FFEF000 +-----------------+ | - | BL32 | | + 0x2FFFF000 +-----------------+ | + | SCMI mailbox | | 0x30000000 +-----------------+ / | | | ... | @@ -102,23 +115,110 @@ Available storage medias are: - ``STM32MP_SPI_NAND`` - ``STM32MP_SPI_NOR`` -To build with SP_min and support for all bootable devices: +Boot with FIP +~~~~~~~~~~~~~ +You need to build BL2, BL32 (SP_min or OP-TEE) and BL33 (U-Boot) before building FIP binary. + +U-Boot +______ + +.. code:: bash + + cd + make stm32mp15_trusted_defconfig + make DEVICE_TREE=stm32mp157c-ev1 all + +OP-TEE (optional) +_________________ + +.. code:: bash + + cd + make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \ + CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts + + +TF-A BL32 (SP_min) +__________________ +If you choose not to use OP-TEE, you can use TF-A SP_min. +To build TF-A BL32, and its device tree file: + +.. code:: bash + + make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb bl32 dtbs + +TF-A BL2 +________ +To build TF-A BL2 with its STM32 header for SD-card boot: + +.. code:: bash + + make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + DTB_FILE_NAME=stm32mp157c-ev1.dtb STM32MP_SDMMC=1 + +For other boot devices, you have to replace STM32MP_SDMMC in the previous command +with the desired device flag. + +This BL2 is independent of the BL32 used (SP_min or OP-TEE) + + +FIP +___ +With BL32 SP_min: .. code:: bash - make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 - STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb + make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + AARCH32_SP=sp_min \ + DTB_FILE_NAME=stm32mp157c-ev1.dtb \ + BL33=/u-boot-nodtb.bin \ + BL33_CFG=/u-boot.dtb \ + fip + +With OP-TEE: + +.. code:: bash + + make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + DTB_FILE_NAME=stm32mp157c-ev1.dtb \ + BL33=/u-boot-nodtb.bin \ + BL33_CFG=/u-boot.dtb \ + BL32=/tee-header_v2.bin \ + BL32_EXTRA1=/tee-pager_v2.bin + BL32_EXTRA2=/tee-pageable_v2.bin + fip + + +STM32IMAGE bootchain +~~~~~~~~~~~~~~~~~~~~ +You need to add the following flag to the make command: +``STM32MP_USE_STM32IMAGE=1`` + +To build with SP_min and support for SD-card boot: + +.. code:: bash + + make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + AARCH32_SP=sp_min STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \ + STM32MP_USE_STM32IMAGE=1 + cd make stm32mp15_trusted_defconfig make DEVICE_TREE=stm32mp157c-ev1 all -To build TF-A with OP-TEE support for all bootable devices: +To build TF-A with OP-TEE support for SD-card boot: .. code:: bash - make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb + make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + AARCH32_SP=optee STM32MP_SDMMC=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb \ + STM32MP_USE_STM32IMAGE=1 + cd - make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts + make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 \ + CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts + cd make stm32mp15_trusted_defconfig make DEVICE_TREE=stm32mp157c-ev1 all @@ -132,7 +232,19 @@ The following build options are supported: Populate SD-card ---------------- -The SD-card has to be formated with GPT. +Boot with FIP +~~~~~~~~~~~~~ +The SD-card has to be formatted with GPT. +It should contain at least those partitions: + +- fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary (BL2) +- fip: which contains the FIP binary + +Usually, two copies of fsbl are used (fsbl1 and fsbl2) instead of one partition fsbl. + +STM32IMAGE bootchain +~~~~~~~~~~~~~~~~~~~~ +The SD-card has to be formatted with GPT. It should contain at least those partitions: - fsbl: to copy the tf-a-stm32mp157c-ev1.stm32 binary -- cgit v1.2.3 From 975563dbfc012b6e8a7765dd8e48220e1bc53dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 26 Aug 2021 17:29:45 +0200 Subject: fix(plat/marvell/a3k): enable workaround for erratum 1530924 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Erratum 1530924 affects Armada 37xx CPU, since it affects all Cortex-A53 revisions from r0p0 to r0p4. Enable the workaround for this erratum. Signed-off-by: Marek Behún Change-Id: I753225040e49e956788d5617cd7ce76d5e6ea8e8 --- plat/marvell/armada/a3k/common/a3700_common.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 238587d6a..955045221 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -13,6 +13,7 @@ PLAT_INCLUDE_BASE := $(MARVELL_PLAT_INCLUDE_BASE)/$(PLAT_FAMILY) PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common MARVELL_DRV_BASE := drivers/marvell MARVELL_COMMON_BASE := $(MARVELL_PLAT_BASE)/common +ERRATA_A53_1530924 := 1 include plat/marvell/marvell.mk -- cgit v1.2.3 From d0bbe8150eb35fe2bac1567751bf84a8f073dd39 Mon Sep 17 00:00:00 2001 From: Jayanth Dodderi Chidanand Date: Thu, 9 Sep 2021 14:23:10 +0100 Subject: fix(docs-contributing.rst): fix formatting for code snippet This patch will fix the formatting errors concerning code snippet, lines 245 and 256 respectively. The code snippet is updated to 'shell' to lex it appropriately. Signed-off-by: Jayanth Dodderi Chidanand Change-Id: I53aefd81da350b6511e7a97b5fee7b0d6f9dde2d --- docs/process/contributing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index a0d068322..aa050dabe 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -242,7 +242,7 @@ Add Build Configurations #. For better understanding follow the below specified examples listed in the ``tf-cov-make`` script. -.. code:: c +.. code:: shell Example 1: #Intel @@ -253,7 +253,7 @@ Add Build Configurations under the Intel platform and the build configurations has been added suitably to include most of their source files. -.. code:: c +.. code:: shell Example 2: #Hikey -- cgit v1.2.3 From f2dcf41826c61b8a47a0f3e44600d7fa121ef921 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 21 Jun 2021 09:47:13 +0200 Subject: refactor(spmd): boot interface and pass core id This change refactors the SPMD to setup SPMC CPU contexts once and early from spmd_spmc_init (single call to cm_setup_context rather than on each and every warm boot). Pass the core linear ID through a GP register as an implementation defined behavior helping FF-A adoption to legacy TOSes (essentially when secure virtualization is not used). A first version of this change was originally submitted by Lukas [1]. Pasting below the original justification: Our TEE, Kinibi, is used to receive the core linear ID in the x3 register of booting secondary cores. This patch is necessary to bring up secondary cores with Kinibi as an SPMC in SEL1. In Kinibi, the TEE is mostly platform-independent and all platform- specifics like topology is concentrated in TF-A of our customers. That is why we don't have the MPIDR - linear ID mapping in Kinibi. We need the correct linear ID to program the GICv2 target register, for example in power management case. It is not needed on GICv3/v4, because of using a fixed mapping from MPIDR to ICDIPTR/GICD_ITARGETSRn register. For debug and power management purpose, we also want a unified view to linear id between Linux and the TEE. E.g. to disable a core, to see what cores are printing a trace / an event. In the past, Kinibi had several other designs, but the complexity was getting out of control: * Platform-specific assembler macros in the kernel. * A per-core SMC from Linux to tell the linear ID after the boot. * With DynamiQ, it seems SIPs were playing with MPIDR register values, reusing them between cores and changing them during boot. [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/10235 Signed-off-by: Olivier Deprez Signed-off-by: Lukas Hanel Change-Id: Ifa8fa208e9b8eb1642c80b5f7b54152dadafa75e --- docs/components/secure-partition-manager.rst | 14 ++++++++-- services/std_svc/spmd/spmd_main.c | 42 +++++++++++++--------------- services/std_svc/spmd/spmd_pm.c | 18 ++++++++---- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index a5e7e8ed5..0b8008306 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -414,13 +414,17 @@ SPMC boot The SPMC is loaded by BL2 as the BL32 image. -The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image. +The SPMC manifest is loaded by BL2 as the ``TOS_FW_CONFIG`` image `[9]`_. BL2 passes the SPMC manifest address to BL31 through a register. At boot time, the SPMD in BL31 runs from the primary core, initializes the core -contexts and launches the SPMC (BL32) passing the SPMC manifest address through -a register. +contexts and launches the SPMC (BL32) passing the following information through +registers: + +- X0 holds the ``TOS_FW_CONFIG`` physical address (or SPMC manifest blob). +- X1 holds the ``HW_CONFIG`` physical address. +- X4 holds the currently running core linear id. Loading of SPs ~~~~~~~~~~~~~~ @@ -951,6 +955,10 @@ Client `__ [8] https://lists.trustedfirmware.org/pipermail/tf-a/2020-February/000296.html +.. _[9]: + +[9] https://trustedfirmware-a.readthedocs.io/en/latest/design/firmware-design.html#dynamic-configuration-during-cold-boot + -------------- *Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.* diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index dda127fd4..0706c45db 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -64,14 +64,6 @@ spmd_spm_core_context_t *spmd_get_context(void) return spmd_get_context_by_mpidr(read_mpidr()); } -/******************************************************************************* - * SPM Core entry point information get helper. - ******************************************************************************/ -entry_point_info_t *spmd_spmc_ep_info_get(void) -{ - return spmc_ep_info; -} - /******************************************************************************* * SPM Core ID getter. ******************************************************************************/ @@ -156,18 +148,11 @@ static int32_t spmd_init(void) { spmd_spm_core_context_t *ctx = spmd_get_context(); uint64_t rc; - unsigned int linear_id = plat_my_core_pos(); - unsigned int core_id; VERBOSE("SPM Core init start.\n"); - ctx->state = SPMC_STATE_ON_PENDING; - /* Set the SPMC context state on other CPUs to OFF */ - for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) { - if (core_id != linear_id) { - spm_core_context[core_id].state = SPMC_STATE_OFF; - } - } + /* Primary boot core enters the SPMC for initialization. */ + ctx->state = SPMC_STATE_ON_PENDING; rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { @@ -187,7 +172,8 @@ static int32_t spmd_init(void) ******************************************************************************/ static int spmd_spmc_init(void *pm_addr) { - spmd_spm_core_context_t *spm_ctx = spmd_get_context(); + cpu_context_t *cpu_ctx; + unsigned int core_id; uint32_t ep_attr; int rc; @@ -280,13 +266,21 @@ static int spmd_spmc_init(void *pm_addr) DISABLE_ALL_EXCEPTIONS); } - /* Initialise SPM Core context with this entry point information */ - cm_setup_context(&spm_ctx->cpu_ctx, spmc_ep_info); + /* Set an initial SPMC context state for all cores. */ + for (core_id = 0U; core_id < PLATFORM_CORE_COUNT; core_id++) { + spm_core_context[core_id].state = SPMC_STATE_OFF; - /* Reuse PSCI affinity states to mark this SPMC context as off */ - spm_ctx->state = AFF_STATE_OFF; + /* Setup an initial cpu context for the SPMC. */ + cpu_ctx = &spm_core_context[core_id].cpu_ctx; + cm_setup_context(cpu_ctx, spmc_ep_info); - INFO("SPM Core setup done.\n"); + /* + * Pass the core linear ID to the SPMC through x4. + * (TF-A implementation defined behavior helping + * a legacy TOS migration to adopt FF-A). + */ + write_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4, core_id); + } /* Register power management hooks with PSCI */ psci_register_spd_pm_hook(&spmd_pm); @@ -294,6 +288,8 @@ static int spmd_spmc_init(void *pm_addr) /* Register init function for deferred init. */ bl31_register_bl32_init(&spmd_init); + INFO("SPM Core setup done.\n"); + return 0; } diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index 074609c89..ac962eaa2 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -75,14 +75,14 @@ out: ******************************************************************************/ static void spmd_cpu_on_finish_handler(u_register_t unused) { - entry_point_info_t *spmc_ep_info = spmd_spmc_ep_info_get(); spmd_spm_core_context_t *ctx = spmd_get_context(); unsigned int linear_id = plat_my_core_pos(); + el3_state_t *el3_state; + uintptr_t entry_point; uint64_t rc; assert(ctx != NULL); assert(ctx->state != SPMC_STATE_ON); - assert(spmc_ep_info != NULL); spin_lock(&g_spmd_pm.lock); @@ -92,14 +92,20 @@ static void spmd_cpu_on_finish_handler(u_register_t unused) * primary core address for booting secondary cores. */ if (g_spmd_pm.secondary_ep_locked == true) { - spmc_ep_info->pc = g_spmd_pm.secondary_ep; + /* + * The CPU context has already been initialized at boot time + * (in spmd_spmc_init by a call to cm_setup_context). Adjust + * below the target core entry point based on the address + * passed to by FFA_SECONDARY_EP_REGISTER. + */ + entry_point = g_spmd_pm.secondary_ep; + el3_state = get_el3state_ctx(&ctx->cpu_ctx); + write_ctx_reg(el3_state, CTX_ELR_EL3, entry_point); } spin_unlock(&g_spmd_pm.lock); - cm_setup_context(&ctx->cpu_ctx, spmc_ep_info); - - /* Mark CPU as initiating ON operation */ + /* Mark CPU as initiating ON operation. */ ctx->state = SPMC_STATE_ON_PENDING; rc = spmd_spm_core_sync_entry(ctx); -- cgit v1.2.3 From bb273e3be1c4f1cddeac9ceaac95fb56e41e6b98 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 18:58:23 +0900 Subject: fix(drivers/rcar3): console: fix a return value of console_rcar_init This commit fixes a return value of console_rcar_init because it is expected to return 1 on success but the function always returns 0. Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I97a6800578e3c517c0c1e3c00dc75f0ef75e8778 --- drivers/renesas/common/console/rcar_console.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/renesas/common/console/rcar_console.S b/drivers/renesas/common/console/rcar_console.S index 29baa67a4..b683d7bfb 100644 --- a/drivers/renesas/common/console/rcar_console.S +++ b/drivers/renesas/common/console/rcar_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -63,7 +63,7 @@ endfunc console_rcar_register * --------------------------------------------- */ func console_rcar_init - mov w0, #0 + mov w0, #1 ret endfunc console_rcar_init -- cgit v1.2.3 From fb3406b6b573cb0b35138ca3c89c5641d3d7b790 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:43:45 +0900 Subject: fix(plat/rcar3): fix source file to make about GICv2 Changed the plat/renesas/common/common.mk to change the source files about GICv2 by include gicv2.mk, because gic_common.c has deprecated. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: Iaa7eae6b2c1dd79a05339325e6bc422d87bce49e --- plat/renesas/common/common.mk | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index fafce9834..7f696356c 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. +# Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -77,9 +77,8 @@ PLAT_INCLUDES := -Iplat/renesas/common/include/registers \ PLAT_BL_COMMON_SOURCES := drivers/renesas/common/iic_dvfs/iic_dvfs.c \ plat/renesas/common/rcar_common.c -RCAR_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ +include drivers/arm/gic/v2/gicv2.mk +RCAR_GIC_SOURCES := ${GICV2_SOURCES} \ plat/common/plat_gicv2.c BL2_SOURCES += ${RCAR_GIC_SOURCES} \ -- cgit v1.2.3 From c3d192b8e52823dcbc32e21e47c30693d38bb49f Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:18:57 +0900 Subject: fix(plat/rcar3): fix version judgment for R-Car D3 Added the process of judgment and logging for R-Car D3 Ver.1.1 and Ver.1.0. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I326aa42374b70b6a4a71893561a7eaa0b6eddef0 --- plat/renesas/common/include/rcar_def.h | 2 ++ plat/renesas/rcar/bl2_plat_setup.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h index 93a65f1a4..9201b6e21 100644 --- a/plat/renesas/common/include/rcar_def.h +++ b/plat/renesas/common/include/rcar_def.h @@ -151,6 +151,8 @@ /* Product register */ #define RCAR_PRR U(0xFFF00044) #define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ +#define RCAR_D3_CUT_VER10 U(0x00000000) /* D3 Ver.1.0 */ +#define RCAR_D3_CUT_VER11 U(0x00000010) /* D3 Ver.1.1 */ #define RCAR_MAJOR_MASK U(0x000000F0) #define RCAR_MINOR_MASK U(0x0000000F) #define PRR_PRODUCT_SHIFT U(8) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 41b2d11e7..4c5dcd082 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -897,6 +897,14 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, str, (reg & RCAR_MINOR_MASK) + RCAR_M3_MINOR_OFFSET); } + } else if (product == PRR_PRODUCT_D3) { + if (RCAR_D3_CUT_VER10 == (reg & PRR_CUT_MASK)) { + NOTICE("BL2: PRR is R-Car %s Ver.1.0\n", str); + } else if (RCAR_D3_CUT_VER11 == (reg & PRR_CUT_MASK)) { + NOTICE("BL2: PRR is R-Car %s Ver.1.1\n", str); + } else { + NOTICE("BL2: PRR is R-Car %s Ver.X.X\n", str); + } } else { major = (reg & RCAR_MAJOR_MASK) >> RCAR_MAJOR_SHIFT; major = major + RCAR_MAJOR_OFFSET; -- cgit v1.2.3 From 77ab3661e55c39694c7ee81de2d1615775711b64 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:25:09 +0900 Subject: fix(plat/rcar3): fix eMMC boot support for R-Car D3 Fix to support of booting from eMMC (50MHz x 8) on Draak board for R-Car D3. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I0ab2b5c7f8075acbf5f4a69694fb535dddc1a4c8 --- plat/renesas/rcar/bl2_plat_setup.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 4c5dcd082..001347ff9 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -976,10 +976,6 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, str = boot_emmc25x1; break; case MODEMR_BOOT_DEV_EMMC_50X8: -#if RCAR_LSI == RCAR_D3 - ERROR("BL2: Failed to Initialize. eMMC is not supported.\n"); - panic(); -#endif str = boot_emmc50x8; break; default: -- cgit v1.2.3 From a8c0c3e9d0df2215ed3b9ef66f4596787d957566 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:39:19 +0900 Subject: fix(plat/rcar3): fix disabling MFIS write protection for R-Car D3 Fix disabling MFIS write protection for R-Car D3. Signed-off-by: Koichi Yamaguchi Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I8bb5787c09c53dff55d6de89adfcb71157533976 --- plat/renesas/rcar/bl2_plat_setup.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 001347ff9..eebd5af87 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -263,9 +263,6 @@ void bl2_plat_flush_bl31_params(void) if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut) goto tlb; - if (product == PRR_PRODUCT_D3) - goto tlb; - /* Disable MFIS write protection */ mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1); -- cgit v1.2.3 From 2892fedaf27d8bbc68780a4a2c506c768e81b9f1 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:28:58 +0900 Subject: feat(plat/rcar3): apply ERRATA_A53_1530924 and ERRATA_A57_1319537 Apply ERRATA_A53_1530924 and ERRATA_A57_1319537. Signed-off-by: Koichi Yamaguchi Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # Drop Makefile header change, reword commit message Change-Id: I7d6e7e40bad6545a1d96470ce1a6e2d04e042670 --- plat/renesas/common/common.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/renesas/common/common.mk b/plat/renesas/common/common.mk index 7f696356c..0d88d658e 100644 --- a/plat/renesas/common/common.mk +++ b/plat/renesas/common/common.mk @@ -65,10 +65,12 @@ $(eval $(call add_define,RCAR_CUT_30)) ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 +ERRATA_A53_1530924 := 1 # Enable workarounds for selected Cortex-A57 erratas. ERRATA_A57_859972 := 1 ERRATA_A57_813419 := 1 +ERRATA_A57_1319537 := 1 PLAT_INCLUDES := -Iplat/renesas/common/include/registers \ -Iplat/renesas/common/include \ -- cgit v1.2.3 From 42ffd279dd1a686b19e2f1b69d2e35413d5efeba Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:05:06 +0900 Subject: feat(plat/rcar3): use PRR cut to determine DRAM size on M3 The new M3 DRAM size can be determined by the PRR cut version. Read the PRR cut version, and if it is older than cut 30, use legacy DRAM size scheme, else report 8GB in 2GBx4 2ch split. Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # Fix DRAM size judgment by PRR register, reword commit message Change-Id: Ib83176d0d09cab5cae0119ba462e42c66c642798 --- plat/renesas/rcar/bl2_plat_setup.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index eebd5af87..3bd20e230 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2018-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -705,6 +705,7 @@ static void bl2_advertise_dram_size(uint32_t product) [4] = 0x600000000ULL, [6] = 0x700000000ULL, }; + uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; switch (product) { case PRR_PRODUCT_H3: @@ -730,15 +731,21 @@ static void bl2_advertise_dram_size(uint32_t product) break; case PRR_PRODUCT_M3: + if (cut < PRR_PRODUCT_30) { #if (RCAR_GEN3_ULCB == 1) - /* 2GB(1GBx2 2ch split) */ - dram_config[1] = 0x40000000ULL; - dram_config[5] = 0x40000000ULL; + /* 2GB(1GBx2 2ch split) */ + dram_config[1] = 0x40000000ULL; + dram_config[5] = 0x40000000ULL; #else - /* 4GB(2GBx2 2ch split) */ - dram_config[1] = 0x80000000ULL; - dram_config[5] = 0x80000000ULL; + /* 4GB(2GBx2 2ch split) */ + dram_config[1] = 0x80000000ULL; + dram_config[5] = 0x80000000ULL; #endif + } else { + /* 8GB(2GBx4 2ch split) */ + dram_config[1] = 0x100000000ULL; + dram_config[5] = 0x100000000ULL; + } break; case PRR_PRODUCT_M3N: -- cgit v1.2.3 From a4d821a5a625d941f95ec39fb51ac4fc07c46c5c Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 18:43:26 +0900 Subject: feat(plat/rcar3): change the memory map for OP-TEE The memory area size of OP-TEE was changed from 1MB to 2MB because the size of OP-TEE has increased. Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: Ic8a165c83a3a9ef2829f68d5fabeed9ccb6da95e --- plat/renesas/common/include/platform_def.h | 4 ++-- tools/renesas/rcar_layout_create/sa6.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plat/renesas/common/include/platform_def.h b/plat/renesas/common/include/platform_def.h index 72c768891..1213a3c96 100644 --- a/plat/renesas/common/include/platform_def.h +++ b/plat/renesas/common/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -144,7 +144,7 @@ ******************************************************************************/ #ifndef SPD_NONE #define BL32_BASE U(0x44100000) -#define BL32_LIMIT (BL32_BASE + U(0x100000)) +#define BL32_LIMIT (BL32_BASE + U(0x200000)) #endif /******************************************************************************* diff --git a/tools/renesas/rcar_layout_create/sa6.c b/tools/renesas/rcar_layout_create/sa6.c index fa828b9ac..8fafdaded 100644 --- a/tools/renesas/rcar_layout_create/sa6.c +++ b/tools/renesas/rcar_layout_create/sa6.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -96,7 +96,7 @@ #define RCAR_BL32DST_ADDRESS (0x44100000U) #define RCAR_BL32DST_ADDRESSH (0x00000000U) /* Destination size for BL32 */ -#define RCAR_BL32DST_SIZE (0x00040000U) +#define RCAR_BL32DST_SIZE (0x00080000U) /* Destination address for BL33 */ #define RCAR_BL33DST_ADDRESS (0x50000000U) #define RCAR_BL33DST_ADDRESSH (0x00000000U) -- cgit v1.2.3 From 63a7a34706eedba4d13ce6fc661a634801cf8909 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:13:17 +0900 Subject: feat(plat/rcar3): add SYSCEXTMASK bit set/clear in scu_power_up Added the process of SYSECEXTMASK bit set/clear for following power Resume/Shutoff flow. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I71ed22840a42e7ab7d87bfd4241eec6f5ddb129b --- drivers/renesas/common/pwrc/pwrc.c | 22 ++++++++++++++++++++++ plat/renesas/common/include/rcar_def.h | 2 ++ 2 files changed, 24 insertions(+) diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c index 3f60fe633..d29a0267c 100644 --- a/drivers/renesas/common/pwrc/pwrc.c +++ b/drivers/renesas/common/pwrc/pwrc.c @@ -44,6 +44,7 @@ RCAR_INSTANTIATE_LOCK #define CPU_PWR_OFF (0x00000003U) #define RCAR_PSTR_MASK (0x00000003U) #define ST_ALL_STANDBY (0x00003333U) +#define SYSCEXTMASK_EXTMSK0 (0x00000001U) /* Suspend to ram */ #define DBSC4_REG_BASE (0xE6790000U) #define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U) @@ -191,6 +192,8 @@ static void scu_power_up(uint64_t mpidr) { uintptr_t reg_pwrsr, reg_cpumcr, reg_pwron, reg_pwrer; uint32_t c, sysc_reg_bit; + uint32_t lsi_product; + uint32_t lsi_cut; c = rcar_pwrc_get_mpidr_cluster(mpidr); reg_cpumcr = IS_CA57(c) ? RCAR_CA57CPUCMCR : RCAR_CA53CPUCMCR; @@ -205,6 +208,17 @@ static void scu_power_up(uint64_t mpidr) if (mmio_read_32(reg_cpumcr) != 0) mmio_write_32(reg_cpumcr, 0); + lsi_product = mmio_read_32((uintptr_t)RCAR_PRR); + lsi_cut = lsi_product & PRR_CUT_MASK; + lsi_product &= PRR_PRODUCT_MASK; + + if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) || + lsi_product == PRR_PRODUCT_H3 || + lsi_product == PRR_PRODUCT_M3N || + lsi_product == PRR_PRODUCT_E3) { + mmio_setbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0); + } + mmio_setbits_32(RCAR_SYSCIER, sysc_reg_bit); mmio_setbits_32(RCAR_SYSCIMR, sysc_reg_bit); @@ -217,6 +231,14 @@ static void scu_power_up(uint64_t mpidr) while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0) ; mmio_write_32(RCAR_SYSCISR, sysc_reg_bit); + + if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) || + lsi_product == PRR_PRODUCT_H3 || + lsi_product == PRR_PRODUCT_M3N || + lsi_product == PRR_PRODUCT_E3) { + mmio_clrbits_32(RCAR_SYSCEXTMASK, SYSCEXTMASK_EXTMSK0); + } + while ((mmio_read_32(reg_pwrsr) & STATUS_PWRUP) == 0) ; } diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h index 9201b6e21..2cd26edbf 100644 --- a/plat/renesas/common/include/rcar_def.h +++ b/plat/renesas/common/include/rcar_def.h @@ -148,6 +148,8 @@ #define RCAR_PWRER5 U(0xE61801D4) /* shutoff/resume error */ #define RCAR_SYSCISR U(0xE6180004) /* Interrupt status */ #define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */ +#define RCAR_SYSCEXTMASK U(0xE61802F8) /* External Request Mask */ + /* H3/H3-N, M3 v3.0, M3-N, E3 */ /* Product register */ #define RCAR_PRR U(0xFFF00044) #define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ -- cgit v1.2.3 From d10f87674ecee54cffe1ab554cc05733fd16c7f0 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:14:11 +0900 Subject: feat(plat/rcar3): modify operation register from SYSCISR to SYSCISCR Modified the operation register to clearing the state bit of the SYSCISR register from SYSCISR to SYSCISCR. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I9a0820b6414425fa2f4197f60852137827414a4d --- drivers/renesas/common/pwrc/pwrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c index d29a0267c..4ebf04906 100644 --- a/drivers/renesas/common/pwrc/pwrc.c +++ b/drivers/renesas/common/pwrc/pwrc.c @@ -230,7 +230,7 @@ static void scu_power_up(uint64_t mpidr) while ((mmio_read_32(RCAR_SYSCISR) & sysc_reg_bit) == 0) ; - mmio_write_32(RCAR_SYSCISR, sysc_reg_bit); + mmio_write_32(RCAR_SYSCISCR, sysc_reg_bit); if ((lsi_product == PRR_PRODUCT_M3 && lsi_cut >= PRR_PRODUCT_30) || lsi_product == PRR_PRODUCT_H3 || -- cgit v1.2.3 From 7d58aed3b05fa8c677a7c823c1ca5017a462a3d3 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:17:12 +0900 Subject: feat(plat/rcar3): add process to back up X6 and X7 register's value Because the x6 and x7 registers will be overwritten by the callee function, added the processing the register's value push to/pop from stack memory. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I5351a008d3b208a30a8bc8651b8d9b4d1a02a8e8 --- plat/renesas/common/aarch64/plat_helpers.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plat/renesas/common/aarch64/plat_helpers.S b/plat/renesas/common/aarch64/plat_helpers.S index ec21f2510..21c3bedaf 100644 --- a/plat/renesas/common/aarch64/plat_helpers.S +++ b/plat/renesas/common/aarch64/plat_helpers.S @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -284,7 +284,11 @@ func plat_crash_console_putc str x3, [sp, #-16]! str x4, [sp, #-16]! str x5, [sp, #-16]! + str x6, [sp, #-16]! + str x7, [sp, #-16]! bl console_rcar_putc + ldr x7, [sp], #16 + ldr x6, [sp], #16 ldr x5, [sp], #16 ldr x4, [sp], #16 ldr x3, [sp], #16 -- cgit v1.2.3 From 14f0a0817297905c03ddf2c4c6040482ef71d744 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:19:39 +0900 Subject: feat(plat/rcar3): add process of SSCG setting for R-Car D3 - Added the condition where output the SSCG (MD12) setting to log for R-Car D3. - Added the process to switching the bit rate of SCIF by the SSCG (MD12) setting value for R-Car D3. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: Iaf07fa4df12dc233af0b57569ee4fa9329f670a9 --- drivers/renesas/common/scif/scif.S | 26 +++++++++++++++++++------- plat/renesas/rcar/bl2_plat_setup.c | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/renesas/common/scif/scif.S b/drivers/renesas/common/scif/scif.S index beb8dd838..72b5b4bea 100644 --- a/drivers/renesas/common/scif/scif.S +++ b/drivers/renesas/common/scif/scif.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -79,7 +79,7 @@ SCSMR_STOP_1 + \ SCSMR_CKS_DIV1) #define SCBRR_115200BPS (17) -#define SCBRR_115200BPSON (16) +#define SCBRR_115200BPS_D3_SSCG (16) #define SCBRR_115200BPS_E3_SSCG (15) #define SCBRR_230400BPS (8) @@ -216,26 +216,38 @@ func console_rcar_init and w1, w1, #PRR_PRODUCT_MASK mov w2, #PRR_PRODUCT_D3 cmp w1, w2 - beq 4f + beq 5f and w1, w1, #PRR_PRODUCT_MASK mov w2, #PRR_PRODUCT_E3 cmp w1, w2 - bne 5f + bne 4f + /* When SSCG(MD12) on (E3) */ ldr x1, =RST_MODEMR ldr w1, [x1] and w1, w1, #MODEMR_MD12 mov w2, #MODEMR_MD12 cmp w1, w2 - bne 5f + bne 4f + /* When SSCG(MD12) on (E3) */ mov w1, #SCBRR_115200BPS_E3_SSCG b 2f 5: - mov w1, #SCBRR_115200BPS + /* In case of D3 */ + ldr x1, =RST_MODEMR + ldr w1, [x1] + and w1, w1, #MODEMR_MD12 + mov w2, #MODEMR_MD12 + cmp w1, w2 + bne 4f + + /* When SSCG(MD12) on (D3) */ + mov w1, #SCBRR_115200BPS_D3_SSCG b 2f 4: - mov w1, #SCBRR_115200BPSON + /* In case of H3/M3/M3N or when SSCG(MD12) is off in E3/D3 */ + mov w1, #SCBRR_115200BPS b 2f 3: mov w1, #SCBRR_230400BPS diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 3bd20e230..e07b96f56 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -916,7 +916,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor); } - if (product == PRR_PRODUCT_E3) { + if (PRR_PRODUCT_E3 == product || PRR_PRODUCT_D3 == product) { reg = mmio_read_32(RCAR_MODEMR); sscg = reg & RCAR_SSCG_MASK; str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; -- cgit v1.2.3 From 71f2239f53cd3137ad6abdaf0334dc53f2f21cb1 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:20:24 +0900 Subject: feat(plat/rcar3): remove access to RMSTPCRn registers in R-Car D3 Because the Realtime module stop control register n (RMSTPCRn) are not supported in R-Car D3. Therefore, remove access to these registers in R-Car D3. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I4647e28d0e176ff97151e9842019ba12cefe5c03 --- plat/renesas/common/bl2_cpg_init.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/plat/renesas/common/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c index ba8e53b58..a6579ebcd 100644 --- a/plat/renesas/common/bl2_cpg_init.c +++ b/plat/renesas/common/bl2_cpg_init.c @@ -40,7 +40,6 @@ static void bl2_system_cpg_init_e3(void); #endif #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3) -static void bl2_realtime_cpg_init_d3(void); static void bl2_system_cpg_init_d3(void); #endif @@ -292,23 +291,6 @@ static void bl2_system_cpg_init_e3(void) #endif #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3) -static void bl2_realtime_cpg_init_d3(void) -{ - /* Realtime Module Stop Control Registers */ - cpg_write(RMSTPCR0, 0x00010000U); - cpg_write(RMSTPCR1, 0xFFFFFFFFU); - cpg_write(RMSTPCR2, 0x00060FDCU); - cpg_write(RMSTPCR3, 0xFFFFFFDFU); - cpg_write(RMSTPCR4, 0x80000184U); - cpg_write(RMSTPCR5, 0x83FFFFFFU); - cpg_write(RMSTPCR6, 0xFFFFFFFFU); - cpg_write(RMSTPCR7, 0xFFFFFFFFU); - cpg_write(RMSTPCR8, 0x00F1FFF7U); - cpg_write(RMSTPCR9, 0xF3F5E016U); - cpg_write(RMSTPCR10, 0xFFFEFFE0U); - cpg_write(RMSTPCR11, 0x000000B7U); -} - static void bl2_system_cpg_init_d3(void) { /* System Module Stop Control Registers */ @@ -356,7 +338,7 @@ void bl2_cpg_init(void) bl2_realtime_cpg_init_e3(); break; case PRR_PRODUCT_D3: - bl2_realtime_cpg_init_d3(); + /* no need */ break; default: panic(); @@ -373,7 +355,7 @@ void bl2_cpg_init(void) #elif RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2E bl2_realtime_cpg_init_e3(); #elif RCAR_LSI == RCAR_D3 - bl2_realtime_cpg_init_d3(); + /* no need */ #else #error "Don't have CPG initialize routine(unknown)." #endif -- cgit v1.2.3 From 042d710d1d917357c5142b340c79978264d3afb1 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:21:38 +0900 Subject: feat(plat/rcar3): update DDR setting for R-Car D3 Update R-Car D3 DDR setting rev.0.02. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I3e3a202fbb0ff1f0f38a968ab5f8633604a46432 --- drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c | 74 +++++++++++++++++++------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c index a49510ed5..f0113f111 100644 --- a/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c +++ b/drivers/renesas/common/ddr/ddr_a/ddr_init_d3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -11,7 +11,11 @@ #include "rcar_def.h" #include "../ddr_regs.h" -#define RCAR_DDR_VERSION "rev.0.01" +#define RCAR_DDR_VERSION "rev.0.02" + +/* Average periodic refresh interval[ns]. Support 3900,7800 */ +#define REFRESH_RATE 3900 + #if RCAR_LSI != RCAR_D3 #error "Don't have DDR initialize routine." @@ -44,7 +48,7 @@ static void init_ddr_d3_1866(void) mmio_write_32(DBSC_DBTR16, 0x09210507); mmio_write_32(DBSC_DBTR17, 0x040E0000); mmio_write_32(DBSC_DBTR18, 0x00000200); - mmio_write_32(DBSC_DBTR19, 0x012B004B); + mmio_write_32(DBSC_DBTR19, 0x0129004B); mmio_write_32(DBSC_DBTR20, 0x020000FB); mmio_write_32(DBSC_DBTR21, 0x00040004); mmio_write_32(DBSC_DBBL, 0x00000000); @@ -54,8 +58,8 @@ static void init_ddr_d3_1866(void) mmio_write_32(DBSC_DBDFICNT_0, 0x00000010); mmio_write_32(DBSC_DBBCAMDIS, 0x00000001); mmio_write_32(DBSC_DBSCHRW1, 0x00000046); - mmio_write_32(DBSC_SCFCTST0, 0x0D020D04); - mmio_write_32(DBSC_SCFCTST1, 0x0306040C); + mmio_write_32(DBSC_SCFCTST0, 0x0C050B03); + mmio_write_32(DBSC_SCFCTST1, 0x0305030C); mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A); mmio_write_32(DBSC_DBCMD, 0x01000001); @@ -101,7 +105,9 @@ static void init_ddr_d3_1866(void) ; mmio_write_32(DBSC_DBPDRGA_0, 0x00000004); - mmio_write_32(DBSC_DBPDRGD_0, 0x0A206F89); + mmio_write_32(DBSC_DBPDRGD_0, + (uint32_t) (REFRESH_RATE * 928 / 125) - 400 + + 0x0A300000); mmio_write_32(DBSC_DBPDRGA_0, 0x00000022); mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B); mmio_write_32(DBSC_DBPDRGA_0, 0x00000023); @@ -117,7 +123,11 @@ static void init_ddr_d3_1866(void) mmio_write_32(DBSC_DBPDRGA_0, 0x00000028); mmio_write_32(DBSC_DBPDRGD_0, 0x00000046); mmio_write_32(DBSC_DBPDRGA_0, 0x00000029); - mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0); + if (REFRESH_RATE > 3900) { + mmio_write_32(DBSC_DBPDRGD_0, 0x00000020); + } else { + mmio_write_32(DBSC_DBPDRGD_0, 0x000000A0); + } mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C); mmio_write_32(DBSC_DBPDRGD_0, 0x81003047); mmio_write_32(DBSC_DBPDRGA_0, 0x00000020); @@ -225,8 +235,10 @@ static void init_ddr_d3_1866(void) mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF); r2 = mmio_read_32(DBSC_DBPDRGD_0); + mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF); mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00)); mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF); + mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF); r2 = mmio_read_32(DBSC_DBPDRGD_0); mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00)); @@ -296,8 +308,10 @@ static void init_ddr_d3_1866(void) mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E); mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010); - mmio_write_32(DBSC_DBCALCNF, 0x0100401B); - mmio_write_32(DBSC_DBRFCNF1, 0x00080E23); + mmio_write_32(DBSC_DBCALCNF, + (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000); + mmio_write_32(DBSC_DBRFCNF1, + (uint32_t) (REFRESH_RATE * 116 / 125) + 0x00080000); mmio_write_32(DBSC_DBRFCNF2, 0x00010000); mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001); mmio_write_32(DBSC_DBRFEN, 0x00000001); @@ -346,6 +360,19 @@ static void init_ddr_d3_1600(void) { uint32_t i, r2, r3, r5, r6, r7, r12; + mmio_write_32(CPG_CPGWPR, 0x5A5AFFFF); + mmio_write_32(CPG_CPGWPCR, 0xA5A50000); + + mmio_write_32(CPG_SRCR4, 0x20000000); + + mmio_write_32(0xE61500DC, 0xe2200000); + while (!(mmio_read_32(CPG_PLLECR) & BIT(11))) + ; + + mmio_write_32(CPG_SRSTCLR4, 0x20000000); + + mmio_write_32(CPG_CPGWPCR, 0xA5A50001); + mmio_write_32(DBSC_DBSYSCNT0, 0x00001234); mmio_write_32(DBSC_DBKIND, 0x00000007); mmio_write_32(DBSC_DBMEMCONF_0_0, 0x0f030a01); @@ -363,14 +390,14 @@ static void init_ddr_d3_1600(void) mmio_write_32(DBSC_DBTR10, 0x0000000C); mmio_write_32(DBSC_DBTR11, 0x0000000A); mmio_write_32(DBSC_DBTR12, 0x00120012); - mmio_write_32(DBSC_DBTR13, 0x000000D0); + mmio_write_32(DBSC_DBTR13, 0x000000CE); mmio_write_32(DBSC_DBTR14, 0x00140005); mmio_write_32(DBSC_DBTR15, 0x00050004); mmio_write_32(DBSC_DBTR16, 0x071F0305); mmio_write_32(DBSC_DBTR17, 0x040C0000); mmio_write_32(DBSC_DBTR18, 0x00000200); mmio_write_32(DBSC_DBTR19, 0x01000040); - mmio_write_32(DBSC_DBTR20, 0x020000D8); + mmio_write_32(DBSC_DBTR20, 0x020000D6); mmio_write_32(DBSC_DBTR21, 0x00040004); mmio_write_32(DBSC_DBBL, 0x00000000); mmio_write_32(DBSC_DBODT0, 0x00000001); @@ -379,8 +406,8 @@ static void init_ddr_d3_1600(void) mmio_write_32(DBSC_DBDFICNT_0, 0x00000010); mmio_write_32(DBSC_DBBCAMDIS, 0x00000001); mmio_write_32(DBSC_DBSCHRW1, 0x00000046); - mmio_write_32(DBSC_SCFCTST0, 0x0D020C04); - mmio_write_32(DBSC_SCFCTST1, 0x0305040C); + mmio_write_32(DBSC_SCFCTST0, 0x0D050B03); + mmio_write_32(DBSC_SCFCTST1, 0x0306030C); mmio_write_32(DBSC_DBPDLK_0, 0x0000A55A); mmio_write_32(DBSC_DBCMD, 0x01000001); @@ -426,13 +453,14 @@ static void init_ddr_d3_1600(void) ; mmio_write_32(DBSC_DBPDRGA_0, 0x00000004); - mmio_write_32(DBSC_DBPDRGD_0, 0x08C05FF0); + mmio_write_32(DBSC_DBPDRGD_0, + (uint32_t) (REFRESH_RATE * 792 / 125) - 400 + 0x08B00000); mmio_write_32(DBSC_DBPDRGA_0, 0x00000022); mmio_write_32(DBSC_DBPDRGD_0, 0x1000040B); mmio_write_32(DBSC_DBPDRGA_0, 0x00000023); mmio_write_32(DBSC_DBPDRGD_0, 0x2D9C0B66); mmio_write_32(DBSC_DBPDRGA_0, 0x00000024); - mmio_write_32(DBSC_DBPDRGD_0, 0x2A88C400); + mmio_write_32(DBSC_DBPDRGD_0, 0x2A88B400); mmio_write_32(DBSC_DBPDRGA_0, 0x00000025); mmio_write_32(DBSC_DBPDRGD_0, 0x30005200); mmio_write_32(DBSC_DBPDRGA_0, 0x00000026); @@ -442,7 +470,11 @@ static void init_ddr_d3_1600(void) mmio_write_32(DBSC_DBPDRGA_0, 0x00000028); mmio_write_32(DBSC_DBPDRGD_0, 0x00000046); mmio_write_32(DBSC_DBPDRGA_0, 0x00000029); - mmio_write_32(DBSC_DBPDRGD_0, 0x00000098); + if (REFRESH_RATE > 3900) { + mmio_write_32(DBSC_DBPDRGD_0, 0x00000018); + } else { + mmio_write_32(DBSC_DBPDRGD_0, 0x00000098); + } mmio_write_32(DBSC_DBPDRGA_0, 0x0000002C); mmio_write_32(DBSC_DBPDRGD_0, 0x81003047); mmio_write_32(DBSC_DBPDRGA_0, 0x00000020); @@ -549,9 +581,11 @@ static void init_ddr_d3_1600(void) mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF); r2 = mmio_read_32(DBSC_DBPDRGD_0); + mmio_write_32(DBSC_DBPDRGA_0, 0x000000AF); mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00)); mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF); r2 = mmio_read_32(DBSC_DBPDRGD_0); + mmio_write_32(DBSC_DBPDRGA_0, 0x000000CF); mmio_write_32(DBSC_DBPDRGD_0, ((r2 + 0x1) & 0xFF) | (r2 & 0xFFFFFF00)); mmio_write_32(DBSC_DBPDRGA_0, 0x000000A0); @@ -620,8 +654,10 @@ static void init_ddr_d3_1600(void) mmio_write_32(DBSC_DBPDRGD_0, 0x0024643E); mmio_write_32(DBSC_DBBUS0CNF1, 0x00000010); - mmio_write_32(DBSC_DBCALCNF, 0x0100401B); - mmio_write_32(DBSC_DBRFCNF1, 0x00080C30); + mmio_write_32(DBSC_DBCALCNF, + (uint32_t) (64000000 / REFRESH_RATE) + 0x01000000); + mmio_write_32(DBSC_DBRFCNF1, + (uint32_t) (REFRESH_RATE * 99 / 125) + 0x00080000); mmio_write_32(DBSC_DBRFCNF2, 0x00010000); mmio_write_32(DBSC_DBDFICUPDCNF, 0x40100001); mmio_write_32(DBSC_DBRFEN, 0x00000001); @@ -693,7 +729,7 @@ int32_t rcar_dram_init(void) ddr_mbps = 1600; } - NOTICE("BL2: DDR%d\n", ddr_mbps); + NOTICE("BL2: DDR%d(%s)\n", ddr_mbps, RCAR_DDR_VERSION); return 0; } -- cgit v1.2.3 From 053c134683cf74fbf4efad311815b806821f1436 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:22:29 +0900 Subject: feat(plat/rcar3): modify SWDT counter setting for R-Car D3 Modified the SWDT counter setting for R-Car D3. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: If1fa12bf644486f3fad3c6b54cda6c4cbb604103 --- drivers/renesas/common/watchdog/swdt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/renesas/common/watchdog/swdt.c b/drivers/renesas/common/watchdog/swdt.c index 1a351ca17..29ef6f430 100644 --- a/drivers/renesas/common/watchdog/swdt.c +++ b/drivers/renesas/common/watchdog/swdt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -78,7 +78,7 @@ static void swdt_disable(void) void rcar_swdt_init(void) { uint32_t rmsk, sr; -#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RZ_G2E) +#if (RCAR_LSI != RCAR_E3) && (RCAR_LSI != RCAR_D3) && (RCAR_LSI != RZ_G2E) uint32_t reg, val, product_cut, chk_data; reg = mmio_read_32(RCAR_PRR); @@ -96,6 +96,8 @@ void rcar_swdt_init(void) #if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E) mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_7p81k); +#elif (RCAR_LSI == RCAR_D3) + mmio_write_32(SWDT_WTCNT, WTCNT_UPPER_BYTE | WTCNT_COUNT_8p13k); #else val = WTCNT_UPPER_BYTE; -- cgit v1.2.3 From 5460f82806752e419fdd6862e8ca9c5fefbee3f2 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:24:29 +0900 Subject: feat(plat/rcar3): modify LifeC register setting for R-Car D3 Modified SECGRP0COND6 and SECGRP1COND6 setting for R-Car D3. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I3f173ac44c11743965c013ef238748b0dc8cabab --- plat/renesas/common/bl2_secure_setting.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/renesas/common/bl2_secure_setting.c b/plat/renesas/common/bl2_secure_setting.c index 095d1f62a..2f8b0011d 100644 --- a/plat/renesas/common/bl2_secure_setting.c +++ b/plat/renesas/common/bl2_secure_setting.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,10 +49,10 @@ static const struct { /* * Bit13: SCEG PKA (secure APB) slave ports * 0: registers accessed from secure resource only - * 1: Reserved[R-Car E3] + * 1: Reserved[R-Car E3/D3] * Bit12: SCEG PKA (public APB) slave ports * 0: registers accessed from secure resource only - * 1: Reserved[R-Car E3] + * 1: Reserved[R-Car E3/D3] * Bit10: SCEG Secure Core slave ports * 0: registers accessed from secure resource only */ @@ -152,14 +152,14 @@ static const struct { * Security group 1 attribute setting for slave ports 6 * Bit13: SCEG PKA (secure APB) slave ports * SecurityGroup3 - * Reserved[R-Car E3] + * Reserved[R-Car E3/D3] * Bit12: SCEG PKA (public APB) slave ports * SecurityGroup3 - * Reserved[R-Car E3] + * Reserved[R-Car E3/D3] * Bit10: SCEG Secure Core slave ports * SecurityGroup3 */ -#if RCAR_LSI == RCAR_E3 +#if RCAR_LSI == RCAR_E3 || RCAR_LSI == RCAR_D3 { SEC_GRP0COND6, 0x00000400U }, { SEC_GRP1COND6, 0x00000400U }, #else /* RCAR_LSI == RCAR_E3 */ -- cgit v1.2.3 From 993d809cc115ce23dd2df1df19dc8bb548cc19cd Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 21 Mar 2021 00:55:48 +0100 Subject: feat(drivers/rcar3): add extra offset if booting B-side In case MFISBTSTSR bit 4 is 1, that means the loader was started as B-side. Load the remaining boot components from 8 MiB offset. Signed-off-by: Marek Vasut Change-Id: I11d882f30ca4f0cf55fd28d3470ff1063d350d10 --- drivers/renesas/common/io/io_rcar.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c index c3e8319de..17d7aaa29 100644 --- a/drivers/renesas/common/io/io_rcar.c +++ b/drivers/renesas/common/io/io_rcar.c @@ -151,6 +151,9 @@ int32_t rcar_get_certificate(const int32_t name, uint32_t *cert) return -EINVAL; } +#define MFISBTSTSR (0xE6260604U) +#define MFISBTSTSR_BOOT_PARTITION (0x00000010U) + static int32_t file_to_offset(const int32_t name, uintptr_t *offset, uint32_t *cert, uint32_t *no_load, uintptr_t *partition) @@ -169,6 +172,9 @@ static int32_t file_to_offset(const int32_t name, uintptr_t *offset, } *offset = rcar_image_header[addr]; + + if (mmio_read_32(MFISBTSTSR) & MFISBTSTSR_BOOT_PARTITION) + *offset += 0x800000; *cert = RCAR_CERT_SIZE; *cert *= RCAR_ATTR_GET_CERTOFF(name_offset[i].attr); *cert += RCAR_SDRAM_certESS; -- cgit v1.2.3 From 899108601a0c3b08ead5e686d92ea0794700ff35 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 21 Mar 2021 01:22:58 +0100 Subject: feat(plat/rcar3): keep RWDT enabled In case the WDT is enabled by prior stage, keep it enabled. Signed-off-by: Marek Vasut Change-Id: Ie7c0eaf2f59dd8c30a9ef686a7000424f38d6352 --- plat/renesas/common/bl2_cpg_init.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plat/renesas/common/bl2_cpg_init.c b/plat/renesas/common/bl2_cpg_init.c index a6579ebcd..a545f7106 100644 --- a/plat/renesas/common/bl2_cpg_init.c +++ b/plat/renesas/common/bl2_cpg_init.c @@ -139,7 +139,7 @@ static void bl2_system_cpg_init_h3(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x040E2FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0xC3FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); @@ -175,7 +175,7 @@ static void bl2_system_cpg_init_m3(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x040E2FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0xC3FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); @@ -211,7 +211,7 @@ static void bl2_system_cpg_init_m3n(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x040E2FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0xC3FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); @@ -245,7 +245,7 @@ static void bl2_system_cpg_init_v3m(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x340E2FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0xC3FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); @@ -279,7 +279,7 @@ static void bl2_system_cpg_init_e3(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x000E2FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x80000004U); + cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0xC3FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); @@ -298,7 +298,7 @@ static void bl2_system_cpg_init_d3(void) cpg_write(SMSTPCR1, 0xFFFFFFFFU); cpg_write(SMSTPCR2, 0x00060FDCU); cpg_write(SMSTPCR3, 0xFFFFFBDFU); - cpg_write(SMSTPCR4, 0x00000084U); + cpg_write(SMSTPCR4, 0x00000080U | (mmio_read_32(SMSTPCR4) & 0x4)); cpg_write(SMSTPCR5, 0x83FFFFFFU); cpg_write(SMSTPCR6, 0xFFFFFFFFU); cpg_write(SMSTPCR7, 0xFFFFFFFFU); -- cgit v1.2.3 From d562130ea9637b885135a5efe41cb98f2365754f Mon Sep 17 00:00:00 2001 From: Dawei Chien Date: Fri, 9 Jul 2021 16:55:51 +0800 Subject: feat(plat/mediatek/mt8195): add vcore-dvfs support Add DVFSRC init flow. Change-Id: Ic5fc78c91359abc12c0f54b01860a7cbe41f3358 Signed-off-by: Dawei Chien --- plat/mediatek/mt8195/drivers/spm/build.mk | 3 +- plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c | 522 ++++++++++++++++++++++ plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h | 328 ++++++++++++++ plat/mediatek/mt8195/include/platform_def.h | 1 + plat/mediatek/mt8195/plat_sip_calls.c | 7 + 5 files changed, 860 insertions(+), 1 deletion(-) create mode 100644 plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c create mode 100644 plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h diff --git a/plat/mediatek/mt8195/drivers/spm/build.mk b/plat/mediatek/mt8195/drivers/spm/build.mk index d1ee09239..28b2d070b 100644 --- a/plat/mediatek/mt8195/drivers/spm/build.mk +++ b/plat/mediatek/mt8195/drivers/spm/build.mk @@ -30,7 +30,8 @@ PLAT_SPM_SOURCE_FILES += \ ${CUR_SPM_FOLDER}/constraints/mt_spm_rc_syspll.c \ ${CUR_SPM_FOLDER}/mt_spm_cond.c \ ${CUR_SPM_FOLDER}/mt_spm_suspend.c \ - ${CUR_SPM_FOLDER}/mt_spm_idle.c + ${CUR_SPM_FOLDER}/mt_spm_idle.c \ + ${CUR_SPM_FOLDER}/mt_spm_vcorefs.c ifeq (${MT_SPM_FEATURE_SUPPORT}, no) PLAT_SPM_DEBUG_CFLAGS += -DATF_PLAT_SPM_UNSUPPORT diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c new file mode 100644 index 000000000..2a9a78926 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VCORE_MAX_OPP 4 +#define DRAM_MAX_OPP 7 + +static bool spm_dvfs_init_done; +static bool dvfs_enable_done; +static int vcore_opp_0_uv = 750000; +static int vcore_opp_1_uv = 650000; +static int vcore_opp_2_uv = 600000; +static int vcore_opp_3_uv = 550000; + +static struct reg_config dvfsrc_init_configs[] = { + { DVFSRC_HRT_REQ_UNIT, 0x0000001E }, + { DVFSRC_DEBOUNCE_TIME, 0x19651965 }, + { DVFSRC_TIMEOUT_NEXTREQ, 0x00000015 }, + { DVFSRC_LEVEL_MASK, 0x000EE000 }, + { DVFSRC_DDR_QOS0, 0x00000019 }, + { DVFSRC_DDR_QOS1, 0x00000026 }, + { DVFSRC_DDR_QOS2, 0x00000033 }, + { DVFSRC_DDR_QOS3, 0x0000003B }, + { DVFSRC_DDR_QOS4, 0x0000004C }, + { DVFSRC_DDR_QOS5, 0x00000066 }, + { DVFSRC_DDR_QOS6, 0x00660066 }, + { DVFSRC_LEVEL_LABEL_0_1, 0x50436053 }, + { DVFSRC_LEVEL_LABEL_2_3, 0x40335042 }, + { DVFSRC_LEVEL_LABEL_4_5, 0x40314032 }, + { DVFSRC_LEVEL_LABEL_6_7, 0x30223023 }, + { DVFSRC_LEVEL_LABEL_8_9, 0x20133021 }, + { DVFSRC_LEVEL_LABEL_10_11, 0x20112012 }, + { DVFSRC_LEVEL_LABEL_12_13, 0x10032010 }, + { DVFSRC_LEVEL_LABEL_14_15, 0x10011002 }, + { DVFSRC_LEVEL_LABEL_16_17, 0x00131000 }, + { DVFSRC_LEVEL_LABEL_18_19, 0x00110012 }, + { DVFSRC_LEVEL_LABEL_20_21, 0x00000010 }, + { DVFSRC_MD_LATENCY_IMPROVE, 0x00000040 }, + { DVFSRC_DDR_REQUEST, 0x00004321 }, + { DVFSRC_DDR_REQUEST3, 0x00000065 }, + { DVFSRC_DDR_ADD_REQUEST, 0x66543210 }, + { DVFSRC_HRT_REQUEST, 0x66654321 }, + { DVFSRC_DDR_REQUEST5, 0x54321000 }, + { DVFSRC_DDR_REQUEST7, 0x66000000 }, + { DVFSRC_VCORE_USER_REQ, 0x00010A29 }, + { DVFSRC_HRT_HIGH_3, 0x18A618A6 }, + { DVFSRC_HRT_HIGH_2, 0x18A61183 }, + { DVFSRC_HRT_HIGH_1, 0x0D690B80 }, + { DVFSRC_HRT_HIGH, 0x070804B0 }, + { DVFSRC_HRT_LOW_3, 0x18A518A5 }, + { DVFSRC_HRT_LOW_2, 0x18A51182 }, + { DVFSRC_HRT_LOW_1, 0x0D680B7F }, + { DVFSRC_HRT_LOW, 0x070704AF }, + { DVFSRC_BASIC_CONTROL_3, 0x00000006 }, + { DVFSRC_INT_EN, 0x00000002 }, + { DVFSRC_QOS_EN, 0x0000407C }, + { DVFSRC_HRT_BW_BASE, 0x00000004 }, + { DVFSRC_PCIE_VCORE_REQ, 0x65908101 }, + { DVFSRC_CURRENT_FORCE, 0x00000001 }, + { DVFSRC_BASIC_CONTROL, 0x6698444B }, + { DVFSRC_BASIC_CONTROL, 0x6698054B }, + { DVFSRC_CURRENT_FORCE, 0x00000000 }, +}; + +static struct pwr_ctrl vcorefs_ctrl = { + .wake_src = R12_REG_CPU_WAKEUP, + + /* default VCORE DVFS is disabled */ + .pcm_flags = (SPM_FLAG_RUN_COMMON_SCENARIO | + SPM_FLAG_DISABLE_VCORE_DVS | SPM_FLAG_DISABLE_VCORE_DFS), + + /* SPM_AP_STANDBY_CON */ + /* [0] */ + .reg_wfi_op = 0, + /* [1] */ + .reg_wfi_type = 0, + /* [2] */ + .reg_mp0_cputop_idle_mask = 0, + /* [3] */ + .reg_mp1_cputop_idle_mask = 0, + /* [4] */ + .reg_mcusys_idle_mask = 0, + /* [25] */ + .reg_md_apsrc_1_sel = 0, + /* [26] */ + .reg_md_apsrc_0_sel = 0, + /* [29] */ + .reg_conn_apsrc_sel = 0, + + /* SPM_SRC_REQ */ + /* [0] */ + .reg_spm_apsrc_req = 0, + /* [1] */ + .reg_spm_f26m_req = 0, + /* [3] */ + .reg_spm_infra_req = 0, + /* [4] */ + .reg_spm_vrf18_req = 0, + /* [7] FIXME: default disable HW Auto S1*/ + .reg_spm_ddr_en_req = 1, + /* [8] */ + .reg_spm_dvfs_req = 0, + /* [9] */ + .reg_spm_sw_mailbox_req = 0, + /* [10] */ + .reg_spm_sspm_mailbox_req = 0, + /* [11] */ + .reg_spm_adsp_mailbox_req = 0, + /* [12] */ + .reg_spm_scp_mailbox_req = 0, + + /* SPM_SRC_MASK */ + /* [0] */ + .reg_sspm_srcclkena_0_mask_b = 1, + /* [1] */ + .reg_sspm_infra_req_0_mask_b = 1, + /* [2] */ + .reg_sspm_apsrc_req_0_mask_b = 1, + /* [3] */ + .reg_sspm_vrf18_req_0_mask_b = 1, + /* [4] */ + .reg_sspm_ddr_en_0_mask_b = 1, + /* [5] */ + .reg_scp_srcclkena_mask_b = 1, + /* [6] */ + .reg_scp_infra_req_mask_b = 1, + /* [7] */ + .reg_scp_apsrc_req_mask_b = 1, + /* [8] */ + .reg_scp_vrf18_req_mask_b = 1, + /* [9] */ + .reg_scp_ddr_en_mask_b = 1, + /* [10] */ + .reg_audio_dsp_srcclkena_mask_b = 1, + /* [11] */ + .reg_audio_dsp_infra_req_mask_b = 1, + /* [12] */ + .reg_audio_dsp_apsrc_req_mask_b = 1, + /* [13] */ + .reg_audio_dsp_vrf18_req_mask_b = 1, + /* [14] */ + .reg_audio_dsp_ddr_en_mask_b = 1, + /* [15] */ + .reg_apu_srcclkena_mask_b = 1, + /* [16] */ + .reg_apu_infra_req_mask_b = 1, + /* [17] */ + .reg_apu_apsrc_req_mask_b = 1, + /* [18] */ + .reg_apu_vrf18_req_mask_b = 1, + /* [19] */ + .reg_apu_ddr_en_mask_b = 1, + /* [20] */ + .reg_cpueb_srcclkena_mask_b = 1, + /* [21] */ + .reg_cpueb_infra_req_mask_b = 1, + /* [22] */ + .reg_cpueb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_cpueb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_cpueb_ddr_en_mask_b = 1, + /* [25] */ + .reg_bak_psri_srcclkena_mask_b = 0, + /* [26] */ + .reg_bak_psri_infra_req_mask_b = 0, + /* [27] */ + .reg_bak_psri_apsrc_req_mask_b = 0, + /* [28] */ + .reg_bak_psri_vrf18_req_mask_b = 0, + /* [29] */ + .reg_bak_psri_ddr_en_mask_b = 0, + + /* SPM_SRC2_MASK */ + /* [0] */ + .reg_msdc0_srcclkena_mask_b = 1, + /* [1] */ + .reg_msdc0_infra_req_mask_b = 1, + /* [2] */ + .reg_msdc0_apsrc_req_mask_b = 1, + /* [3] */ + .reg_msdc0_vrf18_req_mask_b = 1, + /* [4] */ + .reg_msdc0_ddr_en_mask_b = 1, + /* [5] */ + .reg_msdc1_srcclkena_mask_b = 1, + /* [6] */ + .reg_msdc1_infra_req_mask_b = 1, + /* [7] */ + .reg_msdc1_apsrc_req_mask_b = 1, + /* [8] */ + .reg_msdc1_vrf18_req_mask_b = 1, + /* [9] */ + .reg_msdc1_ddr_en_mask_b = 1, + /* [10] */ + .reg_msdc2_srcclkena_mask_b = 1, + /* [11] */ + .reg_msdc2_infra_req_mask_b = 1, + /* [12] */ + .reg_msdc2_apsrc_req_mask_b = 1, + /* [13] */ + .reg_msdc2_vrf18_req_mask_b = 1, + /* [14] */ + .reg_msdc2_ddr_en_mask_b = 1, + /* [15] */ + .reg_ufs_srcclkena_mask_b = 1, + /* [16] */ + .reg_ufs_infra_req_mask_b = 1, + /* [17] */ + .reg_ufs_apsrc_req_mask_b = 1, + /* [18] */ + .reg_ufs_vrf18_req_mask_b = 1, + /* [19] */ + .reg_ufs_ddr_en_mask_b = 1, + /* [20] */ + .reg_usb_srcclkena_mask_b = 1, + /* [21] */ + .reg_usb_infra_req_mask_b = 1, + /* [22] */ + .reg_usb_apsrc_req_mask_b = 1, + /* [23] */ + .reg_usb_vrf18_req_mask_b = 1, + /* [24] */ + .reg_usb_ddr_en_mask_b = 1, + /* [25] */ + .reg_pextp_p0_srcclkena_mask_b = 1, + /* [26] */ + .reg_pextp_p0_infra_req_mask_b = 1, + /* [27] */ + .reg_pextp_p0_apsrc_req_mask_b = 1, + /* [28] */ + .reg_pextp_p0_vrf18_req_mask_b = 1, + /* [29] */ + .reg_pextp_p0_ddr_en_mask_b = 1, + + /* SPM_SRC3_MASK */ + /* [0] */ + .reg_pextp_p1_srcclkena_mask_b = 1, + /* [1] */ + .reg_pextp_p1_infra_req_mask_b = 1, + /* [2] */ + .reg_pextp_p1_apsrc_req_mask_b = 1, + /* [3] */ + .reg_pextp_p1_vrf18_req_mask_b = 1, + /* [4] */ + .reg_pextp_p1_ddr_en_mask_b = 1, + /* [5] */ + .reg_gce0_infra_req_mask_b = 1, + /* [6] */ + .reg_gce0_apsrc_req_mask_b = 1, + /* [7] */ + .reg_gce0_vrf18_req_mask_b = 1, + /* [8] */ + .reg_gce0_ddr_en_mask_b = 1, + /* [9] */ + .reg_gce1_infra_req_mask_b = 1, + /* [10] */ + .reg_gce1_apsrc_req_mask_b = 1, + /* [11] */ + .reg_gce1_vrf18_req_mask_b = 1, + /* [12] */ + .reg_gce1_ddr_en_mask_b = 1, + /* [13] */ + .reg_spm_srcclkena_reserved_mask_b = 1, + /* [14] */ + .reg_spm_infra_req_reserved_mask_b = 1, + /* [15] */ + .reg_spm_apsrc_req_reserved_mask_b = 1, + /* [16] */ + .reg_spm_vrf18_req_reserved_mask_b = 1, + /* [17] */ + .reg_spm_ddr_en_reserved_mask_b = 1, + /* [18] */ + .reg_disp0_apsrc_req_mask_b = 1, + /* [19] */ + .reg_disp0_ddr_en_mask_b = 1, + /* [20] */ + .reg_disp1_apsrc_req_mask_b = 1, + /* [21] */ + .reg_disp1_ddr_en_mask_b = 1, + /* [22] */ + .reg_disp2_apsrc_req_mask_b = 1, + /* [23] */ + .reg_disp2_ddr_en_mask_b = 1, + /* [24] */ + .reg_disp3_apsrc_req_mask_b = 1, + /* [25] */ + .reg_disp3_ddr_en_mask_b = 1, + /* [26] */ + .reg_infrasys_apsrc_req_mask_b = 0, + /* [27] */ + .reg_infrasys_ddr_en_mask_b = 1, + + /* [28] */ + .reg_cg_check_srcclkena_mask_b = 1, + /* [29] */ + .reg_cg_check_apsrc_req_mask_b = 1, + /* [30] */ + .reg_cg_check_vrf18_req_mask_b = 1, + /* [31] */ + .reg_cg_check_ddr_en_mask_b = 1, + + /* SPM_SRC4_MASK */ + /* [8:0] */ + .reg_mcusys_merge_apsrc_req_mask_b = 0x11, + /* [17:9] */ + .reg_mcusys_merge_ddr_en_mask_b = 0x11, + /* [19:18] */ + .reg_dramc_md32_infra_req_mask_b = 0, + /* [21:20] */ + .reg_dramc_md32_vrf18_req_mask_b = 0, + /* [23:22] */ + .reg_dramc_md32_ddr_en_mask_b = 0, + /* [24] */ + .reg_dvfsrc_event_trigger_mask_b = 1, + + /* SPM_WAKEUP_EVENT_MASK2 */ + /* [3:0] */ + .reg_sc_sw2spm_wakeup_mask_b = 0, + /* [4] */ + .reg_sc_adsp2spm_wakeup_mask_b = 0, + /* [8:5] */ + .reg_sc_sspm2spm_wakeup_mask_b = 0, + /* [9] */ + .reg_sc_scp2spm_wakeup_mask_b = 0, + /* [10] */ + .reg_csyspwrup_ack_mask = 0, + /* [11] */ + .reg_csyspwrup_req_mask = 1, + + /* SPM_WAKEUP_EVENT_MASK */ + /* [31:0] */ + .reg_wakeup_event_mask = 0xEFFFFFFF, + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + /* [31:0] */ + .reg_ext_wakeup_event_mask = 0xFFFFFFFF, +}; + +struct spm_lp_scen __spm_vcorefs = { + .pwrctrl = &vcorefs_ctrl, +}; + +static void spm_vcorefs_pwarp_cmd(uint64_t cmd, uint64_t val) +{ + if (cmd < NR_IDX_ALL) { + mt_spm_pmic_wrap_set_cmd(PMIC_WRAP_PHASE_ALLINONE, cmd, val); + } else { + INFO("cmd out of range!\n"); + } +} + +void spm_dvfsfw_init(uint64_t boot_up_opp, uint64_t dram_issue) +{ + if (spm_dvfs_init_done == false) { + mmio_write_32(SPM_DVFS_MISC, (mmio_read_32(SPM_DVFS_MISC) & + ~(SPM_DVFS_FORCE_ENABLE_LSB)) | (SPM_DVFSRC_ENABLE_LSB)); + + mmio_write_32(SPM_DVFS_LEVEL, 0x00000001); + mmio_write_32(SPM_DVS_DFS_LEVEL, 0x00010001); + + spm_dvfs_init_done = true; + } +} + +void __spm_sync_vcore_dvfs_power_control(struct pwr_ctrl *dest_pwr_ctrl, + const struct pwr_ctrl *src_pwr_ctrl) +{ + uint32_t dvfs_mask = SPM_FLAG_DISABLE_VCORE_DVS | + SPM_FLAG_DISABLE_VCORE_DFS | + SPM_FLAG_ENABLE_VOLTAGE_BIN; + + dest_pwr_ctrl->pcm_flags = (dest_pwr_ctrl->pcm_flags & (~dvfs_mask)) | + (src_pwr_ctrl->pcm_flags & dvfs_mask); + + if (dest_pwr_ctrl->pcm_flags_cust) { + dest_pwr_ctrl->pcm_flags_cust = (dest_pwr_ctrl->pcm_flags_cust & (~dvfs_mask)) | + (src_pwr_ctrl->pcm_flags & dvfs_mask); + } +} + +void spm_go_to_vcorefs(uint64_t spm_flags) +{ + __spm_set_power_control(__spm_vcorefs.pwrctrl); + __spm_set_wakeup_event(__spm_vcorefs.pwrctrl); + __spm_set_pcm_flags(__spm_vcorefs.pwrctrl); + __spm_send_cpu_wakeup_event(); +} + +uint64_t spm_vcorefs_args(uint64_t x1, uint64_t x2, uint64_t x3) +{ + uint64_t ret = 0U; + uint64_t cmd = x1; + uint64_t spm_flags; + + switch (cmd) { + case VCOREFS_SMC_CMD_0: + spm_dvfsfw_init(x2, x3); + break; + case VCOREFS_SMC_CMD_1: + spm_flags = SPM_FLAG_RUN_COMMON_SCENARIO; + if (x2 & SPM_FLAG_DISABLE_VCORE_DVS) + spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS; + if (x2 & SPM_FLAG_DISABLE_VCORE_DFS) + spm_flags |= SPM_FLAG_DISABLE_VCORE_DFS; + spm_go_to_vcorefs(spm_flags); + break; + case VCOREFS_SMC_CMD_3: + spm_vcorefs_pwarp_cmd(x2, x3); + break; + case VCOREFS_SMC_CMD_2: + case VCOREFS_SMC_CMD_4: + case VCOREFS_SMC_CMD_5: + case VCOREFS_SMC_CMD_7: + default: + break; + } + return ret; +} + +static void dvfsrc_init(void) +{ + int i; + int count = ARRAY_SIZE(dvfsrc_init_configs); + + if (dvfs_enable_done == false) { + for (i = 0; i < count; i++) { + mmio_write_32(dvfsrc_init_configs[i].offset, + dvfsrc_init_configs[i].val); + } + + mmio_write_32(DVFSRC_QOS_EN, 0x0011007C); + + dvfs_enable_done = true; + } +} + +static void spm_vcorefs_vcore_setting(uint64_t flag) +{ + spm_vcorefs_pwarp_cmd(3, __vcore_uv_to_pmic(vcore_opp_3_uv)); + spm_vcorefs_pwarp_cmd(2, __vcore_uv_to_pmic(vcore_opp_2_uv)); + spm_vcorefs_pwarp_cmd(1, __vcore_uv_to_pmic(vcore_opp_1_uv)); + spm_vcorefs_pwarp_cmd(0, __vcore_uv_to_pmic(vcore_opp_0_uv)); +} + +int spm_vcorefs_get_vcore(unsigned int gear) +{ + int ret_val; + + switch (gear) { + case 3: + ret_val = vcore_opp_0_uv; + case 2: + ret_val = vcore_opp_1_uv; + case 1: + ret_val = vcore_opp_2_uv; + case 0: + default: + ret_val = vcore_opp_3_uv; + } + return ret_val; +} + +uint64_t spm_vcorefs_v2_args(u_register_t x1, u_register_t x2, u_register_t x3, u_register_t *x4) +{ + uint64_t ret = 0U; + uint64_t cmd = x1; + uint64_t spm_flags; + + switch (cmd) { + case VCOREFS_SMC_CMD_INIT: + /* vcore_dvfs init + kick */ + spm_dvfsfw_init(0, 0); + spm_vcorefs_vcore_setting(x3 & 0xF); + spm_flags = SPM_FLAG_RUN_COMMON_SCENARIO; + if (x2 & 0x1) { + spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS; + } + if (x2 & 0x2) { + spm_flags |= SPM_FLAG_DISABLE_VCORE_DFS; + } + spm_go_to_vcorefs(spm_flags); + dvfsrc_init(); + *x4 = 0U; + break; + case VCOREFS_SMC_CMD_OPP_TYPE: + /* get dram type */ + *x4 = 0U; + break; + case VCOREFS_SMC_CMD_FW_TYPE: + *x4 = 0U; + break; + case VCOREFS_SMC_CMD_GET_UV: + *x4 = spm_vcorefs_get_vcore(x2); + break; + case VCOREFS_SMC_CMD_GET_NUM_V: + *x4 = VCORE_MAX_OPP; + break; + case VCOREFS_SMC_CMD_GET_NUM_F: + *x4 = DRAM_MAX_OPP; + break; + default: + break; + } + + return ret; +} diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h new file mode 100644 index 000000000..b08fccebb --- /dev/null +++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.h @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __MT_SPM_VCOREFS__H__ +#define __MT_SPM_VCOREFS__H__ + +int spm_vcorefs_get_vcore(unsigned int gear); +uint64_t spm_vcorefs_v2_args(u_register_t x1, u_register_t x2, u_register_t x3, + u_register_t *x4); + +enum vcorefs_smc_cmd { + VCOREFS_SMC_CMD_0 = 0, + VCOREFS_SMC_CMD_1, + VCOREFS_SMC_CMD_2, + VCOREFS_SMC_CMD_3, + VCOREFS_SMC_CMD_4, + /* check spmfw status */ + VCOREFS_SMC_CMD_5, + + /* get spmfw type */ + VCOREFS_SMC_CMD_6, + + /* get spm reg status */ + VCOREFS_SMC_CMD_7, + + NUM_VCOREFS_SMC_CMD, +}; + +enum vcorefs_smc_cmd_new { + VCOREFS_SMC_CMD_INIT = 0, + VCOREFS_SMC_CMD_KICK = 1, + VCOREFS_SMC_CMD_OPP_TYPE = 2, + VCOREFS_SMC_CMD_FW_TYPE = 3, + VCOREFS_SMC_CMD_GET_UV = 4, + VCOREFS_SMC_CMD_GET_FREQ = 5, + VCOREFS_SMC_CMD_GET_NUM_V = 6, + VCOREFS_SMC_CMD_GET_NUM_F = 7, + VCOREFS_SMC_CMD_FB_ACTION = 8, + /*chip specific setting */ + VCOREFS_SMC_CMD_SET_FREQ = 16, + VCOREFS_SMC_CMD_SET_EFUSE = 17, + VCOREFS_SMC_CMD_GET_EFUSE = 18, + VCOREFS_SMC_CMD_DVFS_HOPPING = 19, + VCOREFS_SMC_CMD_DVFS_HOPPING_STATE = 20, +}; + +enum dvfsrc_channel { + DVFSRC_CHANNEL_1 = 1, + DVFSRC_CHANNEL_2, + DVFSRC_CHANNEL_3, + DVFSRC_CHANNEL_4, + NUM_DVFSRC_CHANNEL, +}; + +#define _VCORE_BASE_UV 400000 +#define _VCORE_STEP_UV 6250 + +/* PMIC */ +#define __vcore_pmic_to_uv(pmic) \ + (((pmic) * _VCORE_STEP_UV) + _VCORE_BASE_UV) + +#define __vcore_uv_to_pmic(uv) /* pmic >= uv */ \ + ((((uv) - _VCORE_BASE_UV) + (_VCORE_STEP_UV - 1)) / _VCORE_STEP_UV) + +struct reg_config { + uint32_t offset; + uint32_t val; +}; + +#define DVFSRC_BASIC_CONTROL (DVFSRC_BASE + 0x0) +#define DVFSRC_SW_REQ1 (DVFSRC_BASE + 0x4) +#define DVFSRC_SW_REQ2 (DVFSRC_BASE + 0x8) +#define DVFSRC_SW_REQ3 (DVFSRC_BASE + 0xC) +#define DVFSRC_SW_REQ4 (DVFSRC_BASE + 0x10) +#define DVFSRC_SW_REQ5 (DVFSRC_BASE + 0x14) +#define DVFSRC_SW_REQ6 (DVFSRC_BASE + 0x18) +#define DVFSRC_SW_REQ7 (DVFSRC_BASE + 0x1C) +#define DVFSRC_SW_REQ8 (DVFSRC_BASE + 0x20) +#define DVFSRC_EMI_REQUEST (DVFSRC_BASE + 0x24) +#define DVFSRC_EMI_REQUEST2 (DVFSRC_BASE + 0x28) +#define DVFSRC_EMI_REQUEST3 (DVFSRC_BASE + 0x2C) +#define DVFSRC_EMI_REQUEST4 (DVFSRC_BASE + 0x30) +#define DVFSRC_EMI_REQUEST5 (DVFSRC_BASE + 0x34) +#define DVFSRC_EMI_REQUEST6 (DVFSRC_BASE + 0x38) +#define DVFSRC_EMI_HRT (DVFSRC_BASE + 0x3C) +#define DVFSRC_EMI_HRT2 (DVFSRC_BASE + 0x40) +#define DVFSRC_EMI_HRT3 (DVFSRC_BASE + 0x44) +#define DVFSRC_EMI_QOS0 (DVFSRC_BASE + 0x48) +#define DVFSRC_EMI_QOS1 (DVFSRC_BASE + 0x4C) +#define DVFSRC_EMI_QOS2 (DVFSRC_BASE + 0x50) +#define DVFSRC_EMI_MD2SPM0 (DVFSRC_BASE + 0x54) +#define DVFSRC_EMI_MD2SPM1 (DVFSRC_BASE + 0x58) +#define DVFSRC_EMI_MD2SPM2 (DVFSRC_BASE + 0x5C) +#define DVFSRC_EMI_MD2SPM0_T (DVFSRC_BASE + 0x60) +#define DVFSRC_EMI_MD2SPM1_T (DVFSRC_BASE + 0x64) +#define DVFSRC_EMI_MD2SPM2_T (DVFSRC_BASE + 0x68) +#define DVFSRC_VCORE_REQUEST (DVFSRC_BASE + 0x6C) +#define DVFSRC_VCORE_REQUEST2 (DVFSRC_BASE + 0x70) +#define DVFSRC_VCORE_REQUEST3 (DVFSRC_BASE + 0x74) +#define DVFSRC_VCORE_REQUEST4 (DVFSRC_BASE + 0x78) +#define DVFSRC_VCORE_HRT (DVFSRC_BASE + 0x7C) +#define DVFSRC_VCORE_HRT2 (DVFSRC_BASE + 0x80) +#define DVFSRC_VCORE_HRT3 (DVFSRC_BASE + 0x84) +#define DVFSRC_VCORE_QOS0 (DVFSRC_BASE + 0x88) +#define DVFSRC_VCORE_QOS1 (DVFSRC_BASE + 0x8C) +#define DVFSRC_VCORE_QOS2 (DVFSRC_BASE + 0x90) +#define DVFSRC_VCORE_MD2SPM0 (DVFSRC_BASE + 0x94) +#define DVFSRC_VCORE_MD2SPM1 (DVFSRC_BASE + 0x98) +#define DVFSRC_VCORE_MD2SPM2 (DVFSRC_BASE + 0x9C) +#define DVFSRC_VCORE_MD2SPM0_T (DVFSRC_BASE + 0xA0) +#define DVFSRC_VCORE_MD2SPM1_T (DVFSRC_BASE + 0xA4) +#define DVFSRC_VCORE_MD2SPM2_T (DVFSRC_BASE + 0xA8) +#define DVFSRC_MD_VSRAM_REMAP (DVFSRC_BASE + 0xBC) +#define DVFSRC_HALT_SW_CONTROL (DVFSRC_BASE + 0xC0) +#define DVFSRC_INT (DVFSRC_BASE + 0xC4) +#define DVFSRC_INT_EN (DVFSRC_BASE + 0xC8) +#define DVFSRC_INT_CLR (DVFSRC_BASE + 0xCC) +#define DVFSRC_BW_MON_WINDOW (DVFSRC_BASE + 0xD0) +#define DVFSRC_BW_MON_THRES_1 (DVFSRC_BASE + 0xD4) +#define DVFSRC_BW_MON_THRES_2 (DVFSRC_BASE + 0xD8) +#define DVFSRC_MD_TURBO (DVFSRC_BASE + 0xDC) +#define DVFSRC_PCIE_VCORE_REQ (DVFSRC_BASE + 0xE0) +#define DVFSRC_VCORE_USER_REQ (DVFSRC_BASE + 0xE4) +#define DVFSRC_DEBOUNCE_FOUR (DVFSRC_BASE + 0xF0) +#define DVFSRC_DEBOUNCE_RISE_FALL (DVFSRC_BASE + 0xF4) +#define DVFSRC_TIMEOUT_NEXTREQ (DVFSRC_BASE + 0xF8) +#define DVFSRC_LEVEL_LABEL_0_1 (DVFSRC_BASE + 0x100) +#define DVFSRC_LEVEL_LABEL_2_3 (DVFSRC_BASE + 0x104) +#define DVFSRC_LEVEL_LABEL_4_5 (DVFSRC_BASE + 0x108) +#define DVFSRC_LEVEL_LABEL_6_7 (DVFSRC_BASE + 0x10C) +#define DVFSRC_LEVEL_LABEL_8_9 (DVFSRC_BASE + 0x110) +#define DVFSRC_LEVEL_LABEL_10_11 (DVFSRC_BASE + 0x114) +#define DVFSRC_LEVEL_LABEL_12_13 (DVFSRC_BASE + 0x118) +#define DVFSRC_LEVEL_LABEL_14_15 (DVFSRC_BASE + 0x11C) +#define DVFSRC_MM_BW_0 (DVFSRC_BASE + 0x200) +#define DVFSRC_MM_BW_1 (DVFSRC_BASE + 0x204) +#define DVFSRC_MM_BW_2 (DVFSRC_BASE + 0x208) +#define DVFSRC_MM_BW_3 (DVFSRC_BASE + 0x20C) +#define DVFSRC_MM_BW_4 (DVFSRC_BASE + 0x210) +#define DVFSRC_MM_BW_5 (DVFSRC_BASE + 0x214) +#define DVFSRC_MM_BW_6 (DVFSRC_BASE + 0x218) +#define DVFSRC_MM_BW_7 (DVFSRC_BASE + 0x21C) +#define DVFSRC_MM_BW_8 (DVFSRC_BASE + 0x220) +#define DVFSRC_MM_BW_9 (DVFSRC_BASE + 0x224) +#define DVFSRC_MM_BW_10 (DVFSRC_BASE + 0x228) +#define DVFSRC_MM_BW_11 (DVFSRC_BASE + 0x22C) +#define DVFSRC_MM_BW_12 (DVFSRC_BASE + 0x230) +#define DVFSRC_MM_BW_13 (DVFSRC_BASE + 0x234) +#define DVFSRC_MM_BW_14 (DVFSRC_BASE + 0x238) +#define DVFSRC_MM_BW_15 (DVFSRC_BASE + 0x23C) +#define DVFSRC_MD_BW_0 (DVFSRC_BASE + 0x240) +#define DVFSRC_MD_BW_1 (DVFSRC_BASE + 0x244) +#define DVFSRC_MD_BW_2 (DVFSRC_BASE + 0x248) +#define DVFSRC_MD_BW_3 (DVFSRC_BASE + 0x24C) +#define DVFSRC_MD_BW_4 (DVFSRC_BASE + 0x250) +#define DVFSRC_MD_BW_5 (DVFSRC_BASE + 0x254) +#define DVFSRC_MD_BW_6 (DVFSRC_BASE + 0x258) +#define DVFSRC_MD_BW_7 (DVFSRC_BASE + 0x25C) +#define DVFSRC_SW_BW_0 (DVFSRC_BASE + 0x260) +#define DVFSRC_SW_BW_1 (DVFSRC_BASE + 0x264) +#define DVFSRC_SW_BW_2 (DVFSRC_BASE + 0x268) +#define DVFSRC_SW_BW_3 (DVFSRC_BASE + 0x26C) +#define DVFSRC_SW_BW_4 (DVFSRC_BASE + 0x270) +#define DVFSRC_SW_BW_5 (DVFSRC_BASE + 0x274) +#define DVFSRC_SW_BW_6 (DVFSRC_BASE + 0x278) +#define DVFSRC_QOS_EN (DVFSRC_BASE + 0x280) +#define DVFSRC_MD_BW_URG (DVFSRC_BASE + 0x284) +#define DVFSRC_ISP_HRT (DVFSRC_BASE + 0x290) +#define DVFSRC_HRT_BW_BASE (DVFSRC_BASE + 0x294) +#define DVFSRC_SEC_SW_REQ (DVFSRC_BASE + 0x304) +#define DVFSRC_EMI_MON_DEBOUNCE_TIME (DVFSRC_BASE + 0x308) +#define DVFSRC_MD_LATENCY_IMPROVE (DVFSRC_BASE + 0x30C) +#define DVFSRC_BASIC_CONTROL_3 (DVFSRC_BASE + 0x310) +#define DVFSRC_DEBOUNCE_TIME (DVFSRC_BASE + 0x314) +#define DVFSRC_LEVEL_MASK (DVFSRC_BASE + 0x318) +#define DVFSRC_DEFAULT_OPP (DVFSRC_BASE + 0x31C) +#define DVFSRC_95MD_SCEN_EMI0 (DVFSRC_BASE + 0x500) +#define DVFSRC_95MD_SCEN_EMI1 (DVFSRC_BASE + 0x504) +#define DVFSRC_95MD_SCEN_EMI2 (DVFSRC_BASE + 0x508) +#define DVFSRC_95MD_SCEN_EMI3 (DVFSRC_BASE + 0x50C) +#define DVFSRC_95MD_SCEN_EMI0_T (DVFSRC_BASE + 0x510) +#define DVFSRC_95MD_SCEN_EMI1_T (DVFSRC_BASE + 0x514) +#define DVFSRC_95MD_SCEN_EMI2_T (DVFSRC_BASE + 0x518) +#define DVFSRC_95MD_SCEN_EMI3_T (DVFSRC_BASE + 0x51C) +#define DVFSRC_95MD_SCEN_EMI4 (DVFSRC_BASE + 0x520) +#define DVFSRC_95MD_SCEN_BW0 (DVFSRC_BASE + 0x524) +#define DVFSRC_95MD_SCEN_BW1 (DVFSRC_BASE + 0x528) +#define DVFSRC_95MD_SCEN_BW2 (DVFSRC_BASE + 0x52C) +#define DVFSRC_95MD_SCEN_BW3 (DVFSRC_BASE + 0x530) +#define DVFSRC_95MD_SCEN_BW0_T (DVFSRC_BASE + 0x534) +#define DVFSRC_95MD_SCEN_BW1_T (DVFSRC_BASE + 0x538) +#define DVFSRC_95MD_SCEN_BW2_T (DVFSRC_BASE + 0x53C) +#define DVFSRC_95MD_SCEN_BW3_T (DVFSRC_BASE + 0x540) +#define DVFSRC_95MD_SCEN_BW4 (DVFSRC_BASE + 0x544) +#define DVFSRC_MD_LEVEL_SW_REG (DVFSRC_BASE + 0x548) +#define DVFSRC_RSRV_0 (DVFSRC_BASE + 0x600) +#define DVFSRC_RSRV_1 (DVFSRC_BASE + 0x604) +#define DVFSRC_RSRV_2 (DVFSRC_BASE + 0x608) +#define DVFSRC_RSRV_3 (DVFSRC_BASE + 0x60C) +#define DVFSRC_RSRV_4 (DVFSRC_BASE + 0x610) +#define DVFSRC_RSRV_5 (DVFSRC_BASE + 0x614) +#define DVFSRC_SPM_RESEND (DVFSRC_BASE + 0x630) +#define DVFSRC_DEBUG_STA_0 (DVFSRC_BASE + 0x700) +#define DVFSRC_DEBUG_STA_1 (DVFSRC_BASE + 0x704) +#define DVFSRC_DEBUG_STA_2 (DVFSRC_BASE + 0x708) +#define DVFSRC_DEBUG_STA_3 (DVFSRC_BASE + 0x70C) +#define DVFSRC_DEBUG_STA_4 (DVFSRC_BASE + 0x710) +#define DVFSRC_DEBUG_STA_5 (DVFSRC_BASE + 0x714) +#define DVFSRC_EMI_REQUEST7 (DVFSRC_BASE + 0x800) +#define DVFSRC_EMI_HRT_1 (DVFSRC_BASE + 0x804) +#define DVFSRC_EMI_HRT2_1 (DVFSRC_BASE + 0x808) +#define DVFSRC_EMI_HRT3_1 (DVFSRC_BASE + 0x80C) +#define DVFSRC_EMI_QOS3 (DVFSRC_BASE + 0x810) +#define DVFSRC_EMI_QOS4 (DVFSRC_BASE + 0x814) +#define DVFSRC_DDR_REQUEST (DVFSRC_BASE + 0xA00) +#define DVFSRC_DDR_REQUEST2 (DVFSRC_BASE + 0xA04) +#define DVFSRC_DDR_REQUEST3 (DVFSRC_BASE + 0xA08) +#define DVFSRC_DDR_REQUEST4 (DVFSRC_BASE + 0xA0C) +#define DVFSRC_DDR_REQUEST5 (DVFSRC_BASE + 0xA10) +#define DVFSRC_DDR_REQUEST6 (DVFSRC_BASE + 0xA14) +#define DVFSRC_DDR_REQUEST7 (DVFSRC_BASE + 0xA18) +#define DVFSRC_DDR_HRT (DVFSRC_BASE + 0xA1C) +#define DVFSRC_DDR_HRT2 (DVFSRC_BASE + 0xA20) +#define DVFSRC_DDR_HRT3 (DVFSRC_BASE + 0xA24) +#define DVFSRC_DDR_HRT_1 (DVFSRC_BASE + 0xA28) +#define DVFSRC_DDR_HRT2_1 (DVFSRC_BASE + 0xA2C) +#define DVFSRC_DDR_HRT3_1 (DVFSRC_BASE + 0xA30) +#define DVFSRC_DDR_QOS0 (DVFSRC_BASE + 0xA34) +#define DVFSRC_DDR_QOS1 (DVFSRC_BASE + 0xA38) +#define DVFSRC_DDR_QOS2 (DVFSRC_BASE + 0xA3C) +#define DVFSRC_DDR_QOS3 (DVFSRC_BASE + 0xA40) +#define DVFSRC_DDR_QOS4 (DVFSRC_BASE + 0xA44) +#define DVFSRC_DDR_MD2SPM0 (DVFSRC_BASE + 0xA48) +#define DVFSRC_DDR_MD2SPM1 (DVFSRC_BASE + 0xA4C) +#define DVFSRC_DDR_MD2SPM2 (DVFSRC_BASE + 0xA50) +#define DVFSRC_DDR_MD2SPM0_T (DVFSRC_BASE + 0xA54) +#define DVFSRC_DDR_MD2SPM1_T (DVFSRC_BASE + 0xA58) +#define DVFSRC_DDR_MD2SPM2_T (DVFSRC_BASE + 0xA5C) +#define DVFSRC_HRT_REQ_UNIT (DVFSRC_BASE + 0xA60) +#define DVSFRC_HRT_REQ_MD_URG (DVFSRC_BASE + 0xA64) +#define DVFSRC_HRT_REQ_MD_BW_0 (DVFSRC_BASE + 0xA68) +#define DVFSRC_HRT_REQ_MD_BW_1 (DVFSRC_BASE + 0xA6C) +#define DVFSRC_HRT_REQ_MD_BW_2 (DVFSRC_BASE + 0xA70) +#define DVFSRC_HRT_REQ_MD_BW_3 (DVFSRC_BASE + 0xA74) +#define DVFSRC_HRT_REQ_MD_BW_4 (DVFSRC_BASE + 0xA78) +#define DVFSRC_HRT_REQ_MD_BW_5 (DVFSRC_BASE + 0xA7C) +#define DVFSRC_HRT_REQ_MD_BW_6 (DVFSRC_BASE + 0xA80) +#define DVFSRC_HRT_REQ_MD_BW_7 (DVFSRC_BASE + 0xA84) +#define DVFSRC_HRT1_REQ_MD_BW_0 (DVFSRC_BASE + 0xA88) +#define DVFSRC_HRT1_REQ_MD_BW_1 (DVFSRC_BASE + 0xA8C) +#define DVFSRC_HRT1_REQ_MD_BW_2 (DVFSRC_BASE + 0xA90) +#define DVFSRC_HRT1_REQ_MD_BW_3 (DVFSRC_BASE + 0xA94) +#define DVFSRC_HRT1_REQ_MD_BW_4 (DVFSRC_BASE + 0xA98) +#define DVFSRC_HRT1_REQ_MD_BW_5 (DVFSRC_BASE + 0xA9C) +#define DVFSRC_HRT1_REQ_MD_BW_6 (DVFSRC_BASE + 0xAA0) +#define DVFSRC_HRT1_REQ_MD_BW_7 (DVFSRC_BASE + 0xAA4) +#define DVFSRC_HRT_REQ_MD_BW_8 (DVFSRC_BASE + 0xAA8) +#define DVFSRC_HRT_REQ_MD_BW_9 (DVFSRC_BASE + 0xAAC) +#define DVFSRC_HRT_REQ_MD_BW_10 (DVFSRC_BASE + 0xAB0) +#define DVFSRC_HRT1_REQ_MD_BW_8 (DVFSRC_BASE + 0xAB4) +#define DVFSRC_HRT1_REQ_MD_BW_9 (DVFSRC_BASE + 0xAB8) +#define DVFSRC_HRT1_REQ_MD_BW_10 (DVFSRC_BASE + 0xABC) +#define DVFSRC_HRT_REQ_BW_SW_REG (DVFSRC_BASE + 0xAC0) +#define DVFSRC_HRT_REQUEST (DVFSRC_BASE + 0xAC4) +#define DVFSRC_HRT_HIGH_2 (DVFSRC_BASE + 0xAC8) +#define DVFSRC_HRT_HIGH_1 (DVFSRC_BASE + 0xACC) +#define DVFSRC_HRT_HIGH (DVFSRC_BASE + 0xAD0) +#define DVFSRC_HRT_LOW_2 (DVFSRC_BASE + 0xAD4) +#define DVFSRC_HRT_LOW_1 (DVFSRC_BASE + 0xAD8) +#define DVFSRC_HRT_LOW (DVFSRC_BASE + 0xADC) +#define DVFSRC_DDR_ADD_REQUEST (DVFSRC_BASE + 0xAE0) +#define DVFSRC_LAST (DVFSRC_BASE + 0xAE4) +#define DVFSRC_LAST_L (DVFSRC_BASE + 0xAE8) +#define DVFSRC_MD_SCENARIO (DVFSRC_BASE + 0xAEC) +#define DVFSRC_RECORD_0_0 (DVFSRC_BASE + 0xAF0) +#define DVFSRC_RECORD_0_1 (DVFSRC_BASE + 0xAF4) +#define DVFSRC_RECORD_0_2 (DVFSRC_BASE + 0xAF8) +#define DVFSRC_RECORD_0_3 (DVFSRC_BASE + 0xAFC) +#define DVFSRC_RECORD_0_4 (DVFSRC_BASE + 0xB00) +#define DVFSRC_RECORD_0_5 (DVFSRC_BASE + 0xB04) +#define DVFSRC_RECORD_0_6 (DVFSRC_BASE + 0xB08) +#define DVFSRC_RECORD_0_7 (DVFSRC_BASE + 0xB0C) +#define DVFSRC_RECORD_0_L_0 (DVFSRC_BASE + 0xBF0) +#define DVFSRC_RECORD_0_L_1 (DVFSRC_BASE + 0xBF4) +#define DVFSRC_RECORD_0_L_2 (DVFSRC_BASE + 0xBF8) +#define DVFSRC_RECORD_0_L_3 (DVFSRC_BASE + 0xBFC) +#define DVFSRC_RECORD_0_L_4 (DVFSRC_BASE + 0xC00) +#define DVFSRC_RECORD_0_L_5 (DVFSRC_BASE + 0xC04) +#define DVFSRC_RECORD_0_L_6 (DVFSRC_BASE + 0xC08) +#define DVFSRC_RECORD_0_L_7 (DVFSRC_BASE + 0xC0C) +#define DVFSRC_EMI_REQUEST8 (DVFSRC_BASE + 0xCF0) +#define DVFSRC_DDR_REQUEST8 (DVFSRC_BASE + 0xCF4) +#define DVFSRC_EMI_HRT_2 (DVFSRC_BASE + 0xCF8) +#define DVFSRC_EMI_HRT2_2 (DVFSRC_BASE + 0xCFC) +#define DVFSRC_EMI_HRT3_2 (DVFSRC_BASE + 0xD00) +#define DVFSRC_EMI_QOS5 (DVFSRC_BASE + 0xD04) +#define DVFSRC_EMI_QOS6 (DVFSRC_BASE + 0xD08) +#define DVFSRC_DDR_HRT_2 (DVFSRC_BASE + 0xD0C) +#define DVFSRC_DDR_HRT2_2 (DVFSRC_BASE + 0xD10) +#define DVFSRC_DDR_HRT3_2 (DVFSRC_BASE + 0xD14) +#define DVFSRC_DDR_QOS5 (DVFSRC_BASE + 0xD18) +#define DVFSRC_DDR_QOS6 (DVFSRC_BASE + 0xD1C) +#define DVFSRC_VCORE_REQUEST5 (DVFSRC_BASE + 0xD20) +#define DVFSRC_VCORE_HRT_1 (DVFSRC_BASE + 0xD24) +#define DVFSRC_VCORE_HRT2_1 (DVFSRC_BASE + 0xD28) +#define DVFSRC_VCORE_HRT3_1 (DVFSRC_BASE + 0xD2C) +#define DVFSRC_VCORE_QOS3 (DVFSRC_BASE + 0xD30) +#define DVFSRC_VCORE_QOS4 (DVFSRC_BASE + 0xD34) +#define DVFSRC_HRT_HIGH_3 (DVFSRC_BASE + 0xD38) +#define DVFSRC_HRT_LOW_3 (DVFSRC_BASE + 0xD3C) +#define DVFSRC_BASIC_CONTROL_2 (DVFSRC_BASE + 0xD40) +#define DVFSRC_CURRENT_LEVEL (DVFSRC_BASE + 0xD44) +#define DVFSRC_TARGET_LEVEL (DVFSRC_BASE + 0xD48) +#define DVFSRC_LEVEL_LABEL_16_17 (DVFSRC_BASE + 0xD4C) +#define DVFSRC_LEVEL_LABEL_18_19 (DVFSRC_BASE + 0xD50) +#define DVFSRC_LEVEL_LABEL_20_21 (DVFSRC_BASE + 0xD54) +#define DVFSRC_LEVEL_LABEL_22_23 (DVFSRC_BASE + 0xD58) +#define DVFSRC_LEVEL_LABEL_24_25 (DVFSRC_BASE + 0xD5C) +#define DVFSRC_LEVEL_LABEL_26_27 (DVFSRC_BASE + 0xD60) +#define DVFSRC_LEVEL_LABEL_28_29 (DVFSRC_BASE + 0xD64) +#define DVFSRC_LEVEL_LABEL_30_31 (DVFSRC_BASE + 0xD68) +#define DVFSRC_CURRENT_FORCE (DVFSRC_BASE + 0xD6C) +#define DVFSRC_TARGET_FORCE (DVFSRC_BASE + 0xD70) +#define DVFSRC_EMI_ADD_REQUEST (DVFSRC_BASE + 0xD74) + +#endif /* __MT_SPM_VCOREFS__H__ */ diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h index b84e73f6a..a28733394 100644 --- a/plat/mediatek/mt8195/include/platform_def.h +++ b/plat/mediatek/mt8195/include/platform_def.h @@ -31,6 +31,7 @@ #define VPPSYS1_BASE (IO_PHYS + 0x04f00000) #define VDOSYS0_BASE (IO_PHYS + 0x0C01A000) #define VDOSYS1_BASE (IO_PHYS + 0x0C100000) +#define DVFSRC_BASE (IO_PHYS + 0x00012000) /******************************************************************************* * DP/eDP related constants diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c index 99e1eb389..ee36898ca 100644 --- a/plat/mediatek/mt8195/plat_sip_calls.c +++ b/plat/mediatek/mt8195/plat_sip_calls.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include "plat_sip_calls.h" @@ -28,6 +30,11 @@ uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid, ret = dp_secure_handler(x1, x2, &ret_val); SMC_RET2(handle, ret, ret_val); break; + case MTK_SIP_VCORE_CONTROL_ARCH32: + case MTK_SIP_VCORE_CONTROL_ARCH64: + ret = spm_vcorefs_v2_args(x1, x2, x3, &x4); + SMC_RET2(handle, ret, x4); + break; default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); break; -- cgit v1.2.3 From f7f5d2c4cd209c2d21244da4fa442050eb4531ab Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Tue, 3 Aug 2021 16:48:53 +0900 Subject: fix(plat/synquacer): update scmi power domain off handling In the SCMI power domain off handling, configure GIC to prevent interrupt toward to the core to be turned off, and configure CCN to disable coherency when the cluster is turned off. The same operation is done in SCPI power domain off processing. This commit adds the missing operation in SCMI power domain off handling. Signed-off-by: Masahisa Kojima Change-Id: Ib3523de488500c2e8bdc74e4cb8772a1442d9781 --- plat/socionext/synquacer/sq_psci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c index 0c97fcf79..4168df9da 100644 --- a/plat/socionext/synquacer/sq_psci.c +++ b/plat/socionext/synquacer/sq_psci.c @@ -97,6 +97,14 @@ static void sq_power_down_common(const psci_power_state_t *target_state) void sq_pwr_domain_off(const psci_power_state_t *target_state) { #if SQ_USE_SCMI_DRIVER + /* Prevent interrupts from spuriously waking up this cpu */ + sq_gic_cpuif_disable(); + + /* Cluster is to be turned off, so disable coherency */ + if (SQ_CLUSTER_PWR_STATE(target_state) == SQ_LOCAL_STATE_OFF) { + plat_sq_interconnect_exit_coherency(); + } + sq_scmi_off(target_state); #else sq_power_down_common(target_state); -- cgit v1.2.3 From 91566d663b26434813fa674412bb695be1965557 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 06:01:36 +0800 Subject: feat(plat/imx/imx8m/imx8mp): add imx8mp_private.h to the build Allows for exporting of FIP related methods cleanly in a private header. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: Iaaad4e69ef89c8a8a74648647d7fd09cd0fdd12a --- plat/imx/imx8m/imx8mp/include/imx8mp_private.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 plat/imx/imx8m/imx8mp/include/imx8mp_private.h diff --git a/plat/imx/imx8m/imx8mp/include/imx8mp_private.h b/plat/imx/imx8m/imx8mp/include/imx8mp_private.h new file mode 100644 index 000000000..0a02334db --- /dev/null +++ b/plat/imx/imx8m/imx8mp/include/imx8mp_private.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef IMX8MP_PRIVATE_H +#define IMX8MP_PRIVATE_H + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ +void plat_imx_io_setup(void); + +#endif /* IMX8MP_PRIVATE_H */ -- cgit v1.2.3 From 81d1d86c89da9051e245225c1963677b753363c1 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 06:10:32 +0800 Subject: refactor(plat/imx/imx): make imx io-storage logic for TBBR/FIP common This commit makes imx image io-storage logic common for all imx platform. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: I15045ac8f9dfa8cb714e32f9e7475d5eae4e86e4 --- plat/imx/common/imx_io_storage.c | 301 +++++++++++++++++++++++++ plat/imx/imx7/common/imx7.mk | 3 +- plat/imx/imx7/common/imx7_bl2_el3_common.c | 4 +- plat/imx/imx7/common/imx7_io_storage.c | 270 ---------------------- plat/imx/imx7/include/imx7_def.h | 2 +- plat/imx/imx7/picopi/include/platform_def.h | 8 +- plat/imx/imx7/warp7/include/platform_def.h | 8 +- plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c | 2 +- plat/imx/imx8m/imx8mm/imx8mm_io_storage.c | 300 ------------------------ plat/imx/imx8m/imx8mm/include/imx8mm_private.h | 2 +- plat/imx/imx8m/imx8mm/include/platform_def.h | 8 +- plat/imx/imx8m/imx8mm/platform.mk | 2 +- 12 files changed, 321 insertions(+), 589 deletions(-) create mode 100644 plat/imx/common/imx_io_storage.c delete mode 100644 plat/imx/imx7/common/imx7_io_storage.c delete mode 100644 plat/imx/imx8m/imx8mm/imx8mm_io_storage.c diff --git a/plat/imx/common/imx_io_storage.c b/plat/imx/common/imx_io_storage.c new file mode 100644 index 000000000..bb3566297 --- /dev/null +++ b/plat/imx/common/imx_io_storage.c @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const io_dev_connector_t *fip_dev_con; +static uintptr_t fip_dev_handle; + +#ifndef IMX_FIP_MMAP +static const io_dev_connector_t *mmc_dev_con; +static uintptr_t mmc_dev_handle; + +static const io_block_spec_t mmc_fip_spec = { + .offset = IMX_FIP_MMC_BASE, + .length = IMX_FIP_SIZE +}; + +static const io_block_dev_spec_t mmc_dev_spec = { + /* It's used as temp buffer in block driver. */ + .buffer = { + .offset = IMX_FIP_BASE, + /* do we need a new value? */ + .length = IMX_FIP_SIZE + }, + .ops = { + .read = mmc_read_blocks, + .write = mmc_write_blocks, + }, + .block_size = MMC_BLOCK_SIZE, +}; + +static int open_mmc(const uintptr_t spec); + +#else +static const io_dev_connector_t *memmap_dev_con; +static uintptr_t memmap_dev_handle; + +static const io_block_spec_t fip_block_spec = { + .offset = IMX_FIP_BASE, + .length = IMX_FIP_SIZE +}; +static int open_memmap(const uintptr_t spec); +#endif + +static int open_fip(const uintptr_t spec); + +static const io_uuid_spec_t bl31_uuid_spec = { + .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, +}; + +static const io_uuid_spec_t bl32_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32, +}; + +static const io_uuid_spec_t bl32_extra1_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, +}; + +static const io_uuid_spec_t bl32_extra2_uuid_spec = { + .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, +}; + +static const io_uuid_spec_t bl33_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, +}; + +#if TRUSTED_BOARD_BOOT +static const io_uuid_spec_t tb_fw_cert_uuid_spec = { + .uuid = UUID_TRUSTED_BOOT_FW_CERT, +}; + +static const io_uuid_spec_t trusted_key_cert_uuid_spec = { + .uuid = UUID_TRUSTED_KEY_CERT, +}; + +static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { + .uuid = UUID_SOC_FW_KEY_CERT, +}; + +static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { + .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, +}; + +static const io_uuid_spec_t tos_fw_cert_uuid_spec = { + .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, +}; + +static const io_uuid_spec_t soc_fw_content_cert_uuid_spec = { + .uuid = UUID_SOC_FW_CONTENT_CERT, +}; + +static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, +}; + +static const io_uuid_spec_t nt_fw_cert_uuid_spec = { + .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, +}; +#endif /* TRUSTED_BOARD_BOOT */ + +/* TODO: this structure is replicated multiple times. rationalize it ! */ +struct plat_io_policy { + uintptr_t *dev_handle; + uintptr_t image_spec; + int (*check)(const uintptr_t spec); +}; + +static const struct plat_io_policy policies[] = { +#ifndef IMX_FIP_MMAP + [FIP_IMAGE_ID] = { + &mmc_dev_handle, + (uintptr_t)&mmc_fip_spec, + open_mmc + }, +#else + [FIP_IMAGE_ID] = { + &memmap_dev_handle, + (uintptr_t)&fip_block_spec, + open_memmap + }, +#endif + [BL31_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl31_uuid_spec, + open_fip + }, + [BL32_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_uuid_spec, + open_fip + }, + [BL32_EXTRA1_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_extra1_uuid_spec, + open_fip + }, + [BL32_EXTRA2_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl32_extra2_uuid_spec, + open_fip + }, + [BL33_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&bl33_uuid_spec, + open_fip + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_BOOT_FW_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tb_fw_cert_uuid_spec, + open_fip + }, + [SOC_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_key_cert_uuid_spec, + open_fip + }, + [TRUSTED_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_uuid_spec, + open_fip + }, + [TRUSTED_OS_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tos_fw_key_cert_uuid_spec, + open_fip + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&nt_fw_key_cert_uuid_spec, + open_fip + }, + [SOC_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&soc_fw_content_cert_uuid_spec, + open_fip + }, + [TRUSTED_OS_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&tos_fw_cert_uuid_spec, + open_fip + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + &fip_dev_handle, + (uintptr_t)&nt_fw_cert_uuid_spec, + open_fip + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + +static int open_fip(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if a Firmware Image Package is available */ + result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); + if (result == 0) { + result = io_open(fip_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using FIP\n"); + io_close(local_image_handle); + } + } + return result; +} + +#ifndef IMX_FIP_MMAP +static int open_mmc(const uintptr_t spec) +{ + int result; + uintptr_t local_handle; + + result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(mmc_dev_handle, spec, &local_handle); + if (result == 0) { + io_close(local_handle); + } + } + return result; +} +#else +static int open_memmap(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(memmap_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Memmap\n"); + io_close(local_image_handle); + } + } + return result; +} +#endif + +int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result; + const struct plat_io_policy *policy; + + assert(image_id < ARRAY_SIZE(policies)); + + policy = &policies[image_id]; + result = policy->check(policy->image_spec); + assert(result == 0); + + *image_spec = policy->image_spec; + *dev_handle = *policy->dev_handle; + + return result; +} + +void plat_imx_io_setup(void) +{ + int result __unused; + +#ifndef IMX_FIP_MMAP + result = register_io_dev_block(&mmc_dev_con); + assert(result == 0); + + result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec, + &mmc_dev_handle); + assert(result == 0); + +#else + result = register_io_dev_memmap(&memmap_dev_con); + assert(result == 0); + + result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &memmap_dev_handle); + assert(result == 0); +#endif + + result = register_io_dev_fip(&fip_dev_con); + assert(result == 0); + + result = io_dev_open(fip_dev_con, (uintptr_t)NULL, + &fip_dev_handle); + assert(result == 0); +} diff --git a/plat/imx/imx7/common/imx7.mk b/plat/imx/imx7/common/imx7.mk index 3a95772b1..fdde9a9da 100644 --- a/plat/imx/imx7/common/imx7.mk +++ b/plat/imx/imx7/common/imx7.mk @@ -16,6 +16,7 @@ PLAT_INCLUDES := -Idrivers/imx/uart \ -Iplat/imx/imx7/include \ -Idrivers/imx/timer \ -Idrivers/imx/usdhc \ + -Iinclude/common/tbbr # Translation tables library include lib/xlat_tables_v2/xlat_tables.mk @@ -46,7 +47,7 @@ BL2_SOURCES += common/desc_image_load.c \ plat/imx/imx7/common/imx7_bl2_el3_common.c \ plat/imx/imx7/common/imx7_helpers.S \ plat/imx/imx7/common/imx7_image_load.c \ - plat/imx/imx7/common/imx7_io_storage.c \ + plat/imx/common/imx_io_storage.c \ plat/imx/common/aarch32/imx_uart_console.S \ ${XLAT_TABLES_LIB_SRCS} diff --git a/plat/imx/imx7/common/imx7_bl2_el3_common.c b/plat/imx/imx7/common/imx7_bl2_el3_common.c index 7f156e306..4e5028c77 100644 --- a/plat/imx/imx7/common/imx7_bl2_el3_common.c +++ b/plat/imx/imx7/common/imx7_bl2_el3_common.c @@ -173,7 +173,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, console_set_scope(&console, console_scope); /* Open handles to persistent storage */ - plat_imx7_io_setup(); + plat_imx_io_setup(); /* Setup higher-level functionality CAAM, RTC etc */ imx_caam_init(); @@ -183,7 +183,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, VERBOSE("\tOPTEE 0x%08x-0x%08x\n", IMX7_OPTEE_BASE, IMX7_OPTEE_LIMIT); VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT); VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT); - VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX7_FIP_BASE, IMX7_FIP_LIMIT); + VERBOSE("\tFIP 0x%08x-0x%08x\n", IMX_FIP_BASE, IMX_FIP_LIMIT); VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", IMX7_DTB_OVERLAY_BASE, IMX7_DTB_OVERLAY_LIMIT); VERBOSE("\tDTB 0x%08x-0x%08x\n", IMX7_DTB_BASE, IMX7_DTB_LIMIT); VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", IMX7_UBOOT_BASE, IMX7_UBOOT_LIMIT); diff --git a/plat/imx/imx7/common/imx7_io_storage.c b/plat/imx/imx7/common/imx7_io_storage.c deleted file mode 100644 index 977181d0c..000000000 --- a/plat/imx/imx7/common/imx7_io_storage.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; - -#ifndef IMX7_FIP_MMAP -static const io_dev_connector_t *mmc_dev_con; -static uintptr_t mmc_dev_handle; - -static const io_block_spec_t mmc_fip_spec = { - .offset = IMX7_FIP_MMC_BASE, - .length = IMX7_FIP_SIZE -}; - -static const io_block_dev_spec_t mmc_dev_spec = { - /* It's used as temp buffer in block driver. */ - .buffer = { - .offset = IMX7_FIP_BASE, - /* do we need a new value? */ - .length = IMX7_FIP_SIZE - }, - .ops = { - .read = mmc_read_blocks, - .write = mmc_write_blocks, - }, - .block_size = MMC_BLOCK_SIZE, -}; - -static int open_mmc(const uintptr_t spec); - -#else -static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = IMX7_FIP_BASE, - .length = IMX7_FIP_SIZE -}; -static int open_memmap(const uintptr_t spec); -#endif -static int open_fip(const uintptr_t spec); - -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; - -static const io_uuid_spec_t bl32_extra1_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, -}; - -static const io_uuid_spec_t bl32_extra2_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -#if TRUSTED_BOARD_BOOT -static const io_uuid_spec_t tb_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FW_CERT, -}; - -static const io_uuid_spec_t trusted_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t nt_fw_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - -/* TODO: this structure is replicated multiple times. rationalize it ! */ -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { -#ifndef IMX7_FIP_MMAP - [FIP_IMAGE_ID] = { - &mmc_dev_handle, - (uintptr_t)&mmc_fip_spec, - open_mmc - }, -#else - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, -#endif - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra1_uuid_spec, - open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra2_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_cert_uuid_spec, - open_fip - }, - [TRUSTED_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&trusted_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_key_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_cert_uuid_spec, - open_fip - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - -static int open_fip(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - /* See if a Firmware Image Package is available */ - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { - result = io_open(fip_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using FIP\n"); - io_close(local_image_handle); - } - } - return result; -} - -#ifndef IMX7_FIP_MMAP -static int open_mmc(const uintptr_t spec) -{ - int result; - uintptr_t local_handle; - - result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(mmc_dev_handle, spec, &local_handle); - if (result == 0) - io_close(local_handle); - } - return result; -} -#else -static int open_memmap(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(memmap_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using Memmap\n"); - io_close(local_image_handle); - } - } - return result; -} -#endif - -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - assert(result == 0); - - *image_spec = policy->image_spec; - *dev_handle = *policy->dev_handle; - - return result; -} - -void plat_imx7_io_setup(void) -{ - int result __unused; - -#ifndef IMX7_FIP_MMAP - result = register_io_dev_block(&mmc_dev_con); - assert(result == 0); - - result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec, - &mmc_dev_handle); - assert(result == 0); - -#else - result = register_io_dev_memmap(&memmap_dev_con); - assert(result == 0); - - result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - assert(result == 0); - -#endif - result = register_io_dev_fip(&fip_dev_con); - assert(result == 0); - - result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - assert(result == 0); -} diff --git a/plat/imx/imx7/include/imx7_def.h b/plat/imx/imx7/include/imx7_def.h index 77a8ca3a4..d92a2d118 100644 --- a/plat/imx/imx7/include/imx7_def.h +++ b/plat/imx/imx7/include/imx7_def.h @@ -13,7 +13,7 @@ /******************************************************************************* * Function and variable prototypes ******************************************************************************/ -void plat_imx7_io_setup(void); +void plat_imx_io_setup(void); void imx7_platform_setup(u_register_t arg1, u_register_t arg2, u_register_t arg3, u_register_t arg4); diff --git a/plat/imx/imx7/picopi/include/platform_def.h b/plat/imx/imx7/picopi/include/platform_def.h index 141571c67..5f2975ded 100644 --- a/plat/imx/imx7/picopi/include/platform_def.h +++ b/plat/imx/imx7/picopi/include/platform_def.h @@ -92,12 +92,12 @@ #define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE) /* Define FIP image absolute location 0x80000000 - 0x80100000 */ -#define IMX7_FIP_SIZE 0x00100000 -#define IMX7_FIP_BASE (DRAM_BASE) -#define IMX7_FIP_LIMIT (IMX7_FIP_BASE + IMX7_FIP_SIZE) +#define IMX_FIP_SIZE 0x00100000 +#define IMX_FIP_BASE (DRAM_BASE) +#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE) /* Define FIP image location at 1MB offset */ -#define IMX7_FIP_MMC_BASE (1024 * 1024) +#define IMX_FIP_MMC_BASE (1024 * 1024) /* Define the absolute location of DTB 0x83000000 - 0x83100000 */ #define IMX7_DTB_SIZE 0x00100000 diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h index 4afcb5497..683e50d44 100644 --- a/plat/imx/imx7/warp7/include/platform_def.h +++ b/plat/imx/imx7/warp7/include/platform_def.h @@ -94,12 +94,12 @@ #define IMX7_UBOOT_LIMIT (IMX7_UBOOT_BASE + IMX7_UBOOT_SIZE) /* Define FIP image absolute location 0x80000000 - 0x80100000 */ -#define IMX7_FIP_SIZE 0x00100000 -#define IMX7_FIP_BASE (DRAM_BASE) -#define IMX7_FIP_LIMIT (IMX7_FIP_BASE + IMX7_FIP_SIZE) +#define IMX_FIP_SIZE 0x00100000 +#define IMX_FIP_BASE (DRAM_BASE) +#define IMX_FIP_LIMIT (IMX_FIP_BASE + IMX_FIP_SIZE) /* Define FIP image location at 1MB offset */ -#define IMX7_FIP_MMC_BASE (1024 * 1024) +#define IMX_FIP_MMC_BASE (1024 * 1024) /* Define the absolute location of DTB 0x83000000 - 0x83100000 */ #define IMX7_DTB_SIZE 0x00100000 diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c index 937774c43..c39dd93e7 100644 --- a/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c +++ b/plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c @@ -88,7 +88,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, imx8mm_usdhc_setup(); /* Open handles to a FIP image */ - plat_imx8mm_io_setup(); + plat_imx_io_setup(); } void bl2_el3_plat_arch_setup(void) diff --git a/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c b/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c deleted file mode 100644 index ff6687e13..000000000 --- a/plat/imx/imx8m/imx8mm/imx8mm_io_storage.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static const io_dev_connector_t *fip_dev_con; -static uintptr_t fip_dev_handle; - -#ifndef IMX8MM_FIP_MMAP -static const io_dev_connector_t *mmc_dev_con; -static uintptr_t mmc_dev_handle; - -static const io_block_spec_t mmc_fip_spec = { - .offset = IMX8MM_FIP_MMC_BASE, - .length = IMX8MM_FIP_SIZE -}; - -static const io_block_dev_spec_t mmc_dev_spec = { - /* It's used as temp buffer in block driver. */ - .buffer = { - .offset = IMX8MM_FIP_BASE, - /* do we need a new value? */ - .length = IMX8MM_FIP_SIZE - }, - .ops = { - .read = mmc_read_blocks, - .write = mmc_write_blocks, - }, - .block_size = MMC_BLOCK_SIZE, -}; - -static int open_mmc(const uintptr_t spec); - -#else -static const io_dev_connector_t *memmap_dev_con; -static uintptr_t memmap_dev_handle; - -static const io_block_spec_t fip_block_spec = { - .offset = IMX8MM_FIP_BASE, - .length = IMX8MM_FIP_SIZE -}; -static int open_memmap(const uintptr_t spec); -#endif - -static int open_fip(const uintptr_t spec); - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; - -static const io_uuid_spec_t bl32_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32, -}; - -static const io_uuid_spec_t bl32_extra1_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1, -}; - -static const io_uuid_spec_t bl32_extra2_uuid_spec = { - .uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -#if TRUSTED_BOARD_BOOT -static const io_uuid_spec_t tb_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FW_CERT, -}; - -static const io_uuid_spec_t trusted_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_KEY_CERT, -}; - -static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = { - .uuid = UUID_SOC_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_KEY_CERT, -}; - -static const io_uuid_spec_t tos_fw_cert_uuid_spec = { - .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t soc_fw_content_cert_uuid_spec = { - .uuid = UUID_SOC_FW_CONTENT_CERT, -}; - -static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_KEY_CERT, -}; - -static const io_uuid_spec_t nt_fw_cert_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT, -}; -#endif /* TRUSTED_BOARD_BOOT */ - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { -#ifndef IMX8MM_FIP_MMAP - [FIP_IMAGE_ID] = { - &mmc_dev_handle, - (uintptr_t)&mmc_fip_spec, - open_mmc - }, -#else - [FIP_IMAGE_ID] = { - &memmap_dev_handle, - (uintptr_t)&fip_block_spec, - open_memmap - }, -#endif - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - open_fip - }, - [BL32_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_uuid_spec, - open_fip - }, - [BL32_EXTRA1_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra1_uuid_spec, - open_fip - }, - [BL32_EXTRA2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl32_extra2_uuid_spec, - open_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl33_uuid_spec, - open_fip - }, -#if TRUSTED_BOARD_BOOT - [TRUSTED_BOOT_FW_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tb_fw_cert_uuid_spec, - open_fip - }, - [SOC_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&trusted_key_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_key_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_KEY_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_key_cert_uuid_spec, - open_fip - }, - [SOC_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&soc_fw_content_cert_uuid_spec, - open_fip - }, - [TRUSTED_OS_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&tos_fw_cert_uuid_spec, - open_fip - }, - [NON_TRUSTED_FW_CONTENT_CERT_ID] = { - &fip_dev_handle, - (uintptr_t)&nt_fw_cert_uuid_spec, - open_fip - }, -#endif /* TRUSTED_BOARD_BOOT */ -}; - -static int open_fip(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - /* See if a Firmware Image Package is available */ - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { - result = io_open(fip_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using FIP\n"); - io_close(local_image_handle); - } - } - return result; -} - -#ifndef IMX8MM_FIP_MMAP -static int open_mmc(const uintptr_t spec) -{ - int result; - uintptr_t local_handle; - - result = io_dev_init(mmc_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(mmc_dev_handle, spec, &local_handle); - if (result == 0) { - io_close(local_handle); - } - } - return result; -} -#else -static int open_memmap(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(memmap_dev_handle, spec, &local_image_handle); - if (result == 0) { - VERBOSE("Using Memmap\n"); - io_close(local_image_handle); - } - } - return result; -} -#endif - -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - assert(result == 0); - - *image_spec = policy->image_spec; - *dev_handle = *policy->dev_handle; - - return result; -} - -void plat_imx8mm_io_setup(void) -{ - int result __unused; - -#ifndef IMX8MM_FIP_MMAP - result = register_io_dev_block(&mmc_dev_con); - assert(result == 0); - - result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_dev_spec, - &mmc_dev_handle); - assert(result == 0); - -#else - result = register_io_dev_memmap(&memmap_dev_con); - assert(result == 0); - - result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, - &memmap_dev_handle); - assert(result == 0); -#endif - - result = register_io_dev_fip(&fip_dev_con); - assert(result == 0); - - result = io_dev_open(fip_dev_con, (uintptr_t)NULL, - &fip_dev_handle); - assert(result == 0); -} diff --git a/plat/imx/imx8m/imx8mm/include/imx8mm_private.h b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h index 52d13f031..5e0ef972f 100644 --- a/plat/imx/imx8m/imx8mm/include/imx8mm_private.h +++ b/plat/imx/imx8m/imx8mm/include/imx8mm_private.h @@ -10,6 +10,6 @@ /******************************************************************************* * Function and variable prototypes ******************************************************************************/ -void plat_imx8mm_io_setup(void); +void plat_imx_io_setup(void); #endif /* IMX8MM_PRIVATE_H */ diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index 940d22bc1..e86938bcc 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -41,12 +41,12 @@ #define BL2_LIMIT U(0x940000) #define BL31_BASE U(0x900000) #define BL31_LIMIT U(0x920000) -#define IMX8MM_FIP_BASE U(0x40310000) -#define IMX8MM_FIP_SIZE U(0x000300000) -#define IMX8MM_FIP_LIMIT U(FIP_BASE + FIP_SIZE) +#define IMX_FIP_BASE U(0x40310000) +#define IMX_FIP_SIZE U(0x000300000) +#define IMX_FIP_LIMIT U(FIP_BASE + FIP_SIZE) /* Define FIP image location on eMMC */ -#define IMX8MM_FIP_MMC_BASE U(0x100000) +#define IMX_FIP_MMC_BASE U(0x100000) #define PLAT_IMX8MM_BOOT_MMC_BASE U(0x30B50000) /* SD */ #else diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index 186323393..0d0a0f393 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -63,7 +63,7 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_storage.c \ drivers/imx/usdhc/imx_usdhc.c \ plat/imx/imx8m/imx8mm/imx8mm_bl2_mem_params_desc.c \ - plat/imx/imx8m/imx8mm/imx8mm_io_storage.c \ + plat/imx/common/imx_io_storage.c \ plat/imx/imx8m/imx8mm/imx8mm_image_load.c \ lib/optee/optee_utils.c endif -- cgit v1.2.3 From f696843eab5cf0547b6c6307eaccea25678654c4 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 06:10:49 +0800 Subject: feat(plat/imx/imx8m/imx8mp): add initial definition to facilitate FIP layout Adds a number of definitions consistent with the established RSB3720 equivalents specifying number of io_handles and block devices. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: I401e48216d67257137351ee4d0b98904a76fa789 --- plat/imx/imx8m/imx8mp/include/platform_def.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/plat/imx/imx8m/imx8mp/include/platform_def.h b/plat/imx/imx8m/imx8mp/include/platform_def.h index 832bed17e..14b7ea00f 100644 --- a/plat/imx/imx8m/imx8mp/include/platform_def.h +++ b/plat/imx/imx8m/imx8mp/include/platform_def.h @@ -6,6 +6,7 @@ #ifndef PLATFORM_DEF_H #define PLATFORM_DEF_H +#include #include #include @@ -34,8 +35,23 @@ #define PLAT_WAIT_RET_STATE U(1) #define PLAT_STOP_OFF_STATE U(3) +#if defined(NEED_BL2) +#define BL2_BASE U(0x960000) +#define BL2_LIMIT U(0x980000) +#define BL31_BASE U(0x940000) +#define BL31_LIMIT U(0x960000) +#define IMX_FIP_BASE U(0x40310000) +#define IMX_FIP_SIZE U(0x000300000) +#define IMX_FIP_LIMIT U(FIP_BASE + FIP_SIZE) + +/* Define FIP image location on eMMC */ +#define IMX_FIP_MMC_BASE U(0x100000) + +#define PLAT_IMX8MP_BOOT_MMC_BASE U(0x30B50000) /* SD */ +#else #define BL31_BASE U(0x960000) #define BL31_LIMIT U(0x980000) +#endif #define PLAT_PRI_BITS U(3) #define PLAT_SDEI_CRITICAL_PRI 0x10 @@ -44,6 +60,7 @@ /* non-secure uboot base */ #define PLAT_NS_IMAGE_OFFSET U(0x40200000) +#define PLAT_NS_IMAGE_SIZE U(0x00200000) /* GICv3 base address */ #define PLAT_GICD_BASE U(0x38800000) @@ -150,6 +167,10 @@ #define IMX_WDOG_B_RESET +#define MAX_IO_HANDLES 3U +#define MAX_IO_DEVICES 2U +#define MAX_IO_BLOCK_DEVICES 1U + #define GIC_MAP MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW) #define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */ #define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */ -- cgit v1.2.3 From ce0bec6587d5269cb54175326f708e920ac209dd Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 06:12:37 +0800 Subject: refactor(plat/imx/imx8m): make image load logic for TBBR FIP booting common This commit makes the image load logic from imx8mm common for all imx8m platform. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: Ibfe2e9cc09d198cb9e309afaf381a0237a4b82ed --- plat/imx/imx8m/imx8m_image_load.c | 26 ++++++++++++++++++++++++++ plat/imx/imx8m/imx8mm/imx8mm_image_load.c | 26 -------------------------- plat/imx/imx8m/imx8mm/platform.mk | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 plat/imx/imx8m/imx8m_image_load.c delete mode 100644 plat/imx/imx8m/imx8mm/imx8mm_image_load.c diff --git a/plat/imx/imx8m/imx8m_image_load.c b/plat/imx/imx8m/imx8m_image_load.c new file mode 100644 index 000000000..3a030699c --- /dev/null +++ b/plat/imx/imx8m/imx8m_image_load.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +void plat_flush_next_bl_params(void) +{ + flush_bl_params_desc(); +} + +bl_load_info_t *plat_get_bl_image_load_info(void) +{ + return get_bl_load_info_from_mem_params_desc(); +} + +bl_params_t *plat_get_next_bl_params(void) +{ + return get_next_bl_params_from_mem_params_desc(); +} diff --git a/plat/imx/imx8m/imx8mm/imx8mm_image_load.c b/plat/imx/imx8m/imx8mm/imx8mm_image_load.c deleted file mode 100644 index 3a030699c..000000000 --- a/plat/imx/imx8m/imx8mm/imx8mm_image_load.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include - -void plat_flush_next_bl_params(void) -{ - flush_bl_params_desc(); -} - -bl_load_info_t *plat_get_bl_image_load_info(void) -{ - return get_bl_load_info_from_mem_params_desc(); -} - -bl_params_t *plat_get_next_bl_params(void) -{ - return get_next_bl_params_from_mem_params_desc(); -} diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index 0d0a0f393..ac5a80982 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -64,7 +64,7 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/imx/usdhc/imx_usdhc.c \ plat/imx/imx8m/imx8mm/imx8mm_bl2_mem_params_desc.c \ plat/imx/common/imx_io_storage.c \ - plat/imx/imx8m/imx8mm/imx8mm_image_load.c \ + plat/imx/imx8m/imx8m_image_load.c \ lib/optee/optee_utils.c endif -- cgit v1.2.3 From 75fbf5546b7beca93e4782bc35906f9536392e04 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 06:52:57 +0800 Subject: feat(plat/imx/imx8m/imx8mp): add in BL2 with FIP Adds bl2 with FIP to the build required for mbed Linux booting where we do: BootROM -> SPL -> BL2 -> OPTEE -> u-boot If NEED_BL2 is specified then BL2 will be built and BL31 will have its address range modified upwards to accommodate. BL31 must be loaded from a FIP in this case. If NEED_BL2 is not specified then the current BL31 boot flow is unaffected and u-boot SPL will load and execute BL31 directly. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: I78914d6002755f733ea866127cb47982a00f9700 --- plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c | 117 +++++++++++++++++++++ plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c | 94 +++++++++++++++++ plat/imx/imx8m/imx8mp/platform.mk | 56 +++++++++- 3 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c b/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c new file mode 100644 index 000000000..08cbeeb20 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c @@ -0,0 +1,117 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "imx8mp_private.h" +#include +#include +#include +#include +#include +#include + + +static const struct aipstz_cfg aipstz[] = { + {IMX_AIPSTZ1, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ2, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ3, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {IMX_AIPSTZ4, 0x77777777, 0x77777777, .opacr = {0x0, 0x0, 0x0, 0x0, 0x0}, }, + {0}, +}; + +void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_t console; + unsigned int i; + + /* Enable CSU NS access permission */ + for (i = 0U; i < 64; i++) { + mmio_write_32(IMX_CSU_BASE + i * 4, 0x00ff00ff); + } + + imx_aipstz_init(aipstz); + + console_imx_uart_register(IMX_BOOT_UART_BASE, IMX_BOOT_UART_CLK_IN_HZ, + IMX_CONSOLE_BAUDRATE, &console); + + generic_delay_timer_init(); + + /* select the CKIL source to 32K OSC */ + mmio_write_32(IMX_ANAMIX_BASE + ANAMIX_MISC_CTL, 0x1); + + /* Open handles to a FIP image */ + plat_imx_io_setup(); +} + +void bl2_el3_plat_arch_setup(void) +{ +} + +void bl2_platform_setup(void) +{ +} + +int bl2_plat_handle_post_image_load(unsigned int image_id) +{ + int err = 0; + bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); + bl_mem_params_node_t *pager_mem_params = NULL; + bl_mem_params_node_t *paged_mem_params = NULL; + + assert(bl_mem_params); + + switch (image_id) { + case BL32_IMAGE_ID: + pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID); + assert(pager_mem_params); + + paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID); + assert(paged_mem_params); + + err = parse_optee_header(&bl_mem_params->ep_info, + &pager_mem_params->image_info, + &paged_mem_params->image_info); + if (err != 0) { + WARN("OPTEE header parse error.\n"); + } + + break; + default: + /* Do nothing in default case */ + break; + } + + return err; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return COUNTER_FREQUENCY; +} + +void bl2_plat_runtime_setup(void) +{ + return; +} diff --git a/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c b/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c new file mode 100644 index 000000000..f2f6808e8 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +static bl_mem_params_node_t bl2_mem_params_descs[] = { + { + .image_id = BL31_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + SECURE | EXECUTABLE | EP_FIRST_EXE), + .ep_info.pc = BL31_BASE, + .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS), + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, + IMAGE_ATTRIB_PLAT_SETUP), + .image_info.image_base = BL31_BASE, + .image_info.image_max_size = BL31_LIMIT - BL31_BASE, + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + { + .image_id = BL32_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + SECURE | EXECUTABLE), + .ep_info.pc = BL32_BASE, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, 0), + + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_SIZE, + + .next_handoff_image_id = BL33_IMAGE_ID, + }, + { + .image_id = BL32_EXTRA1_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, + image_info_t, IMAGE_ATTRIB_SKIP_LOADING), + .image_info.image_base = BL32_BASE, + .image_info.image_max_size = BL32_SIZE, + + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + { + /* This is a zero sized image so we don't set base or size */ + .image_id = BL32_EXTRA2_IMAGE_ID, + + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, + SECURE | NON_EXECUTABLE), + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + .next_handoff_image_id = INVALID_IMAGE_ID, + }, + { + .image_id = BL33_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, + entry_point_info_t, + NON_SECURE | EXECUTABLE), + # ifdef PRELOADED_BL33_BASE + .ep_info.pc = PLAT_NS_IMAGE_OFFSET, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, + IMAGE_ATTRIB_SKIP_LOADING), + # else + .ep_info.pc = PLAT_NS_IMAGE_OFFSET, + + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = PLAT_NS_IMAGE_OFFSET, + .image_info.image_max_size = PLAT_NS_IMAGE_SIZE, + # endif /* PRELOADED_BL33_BASE */ + + .next_handoff_image_id = INVALID_IMAGE_ID, + } +}; + +REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs); diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk index 6be2f9861..f134f3384 100644 --- a/plat/imx/imx8m/imx8mp/platform.mk +++ b/plat/imx/imx8m/imx8mp/platform.mk @@ -6,7 +6,9 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/include \ - -Iplat/imx/imx8m/imx8mp/include + -Iplat/imx/imx8m/imx8mp/include \ + -Idrivers/imx/usdhc \ + -Iinclude/common/tbbr # Translation tables library include lib/xlat_tables_v2/xlat_tables.mk @@ -40,6 +42,58 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \ ${IMX_GIC_SOURCES} \ ${XLAT_TABLES_LIB_SRCS} +ifeq (${NEED_BL2},yes) +BL2_SOURCES += common/desc_image_load.c \ + plat/imx/common/imx8_helpers.S \ + plat/imx/common/imx_uart_console.S \ + plat/imx/imx8m/imx8mp/imx8mp_bl2_el3_setup.c \ + plat/imx/imx8m/imx8mp/gpc.c \ + plat/imx/imx8m/imx_aipstz.c \ + plat/imx/imx8m/imx_rdc.c \ + plat/imx/imx8m/imx8m_caam.c \ + plat/common/plat_psci_common.c \ + lib/cpus/aarch64/cortex_a53.S \ + drivers/arm/tzc/tzc380.c \ + drivers/delay_timer/delay_timer.c \ + drivers/delay_timer/generic_delay_timer.c \ + ${PLAT_GIC_SOURCES} \ + ${PLAT_DRAM_SOURCES} \ + ${XLAT_TABLES_LIB_SRCS} \ + drivers/mmc/mmc.c \ + drivers/io/io_block.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + drivers/imx/usdhc/imx_usdhc.c \ + plat/imx/imx8m/imx8mp/imx8mp_bl2_mem_params_desc.c \ + plat/imx/common/imx_io_storage.c \ + plat/imx/imx8m/imx8m_image_load.c \ + lib/optee/optee_utils.c +endif + +# Add the build options to pack BLx images and kernel device tree +# in the FIP if the platform requires. +ifneq ($(BL2),) +RESET_TO_BL31 := 0 +$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert)) +endif +ifneq ($(BL32_EXTRA1),) +$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1)) +endif +ifneq ($(BL32_EXTRA2),) +$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2)) +endif +ifneq ($(HW_CONFIG),) +$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config)) +endif + +ifeq (${NEED_BL2},yes) +$(eval $(call add_define,NEED_BL2)) +LOAD_IMAGE_V2 := 1 +# Non-TF Boot ROM +BL2_AT_EL3 := 1 +endif + USE_COHERENT_MEM := 1 RESET_TO_BL31 := 1 A53_DISABLE_NON_TEMPORAL_HINT := 0 -- cgit v1.2.3 From a16ecd2cff36b3a8a76d223f4e272e165c941b31 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 7 Apr 2021 07:18:52 +0800 Subject: feat(plat/imx/imx8m/imx8mp): enable Trusted Boot This patch enables Trusted Boot on the i.MX8MP with BL2 doing image verification from a FIP prior to hand-over to BL31. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: Iac1d1d62ea9858f67326a47c1e5ba377f23f9db5 --- plat/imx/imx8m/imx8mp/imx8mp_rotpk.S | 15 ++++++++++++ plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c | 36 +++++++++++++++++++++++++++ plat/imx/imx8m/imx8mp/platform.mk | 38 +++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_rotpk.S create mode 100644 plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c diff --git a/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S b/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S new file mode 100644 index 000000000..a4c7ce150 --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_rotpk.S @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .global imx8mp_rotpk_hash + .global imx8mp_rotpk_hash_end +imx8mp_rotpk_hash: + /* DER header */ + .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48 + .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 + /* SHA256 */ + .incbin ROTPK_HASH +imx8mp_rotpk_hash_end: diff --git a/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c b/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c new file mode 100644 index 000000000..5d1a6c21b --- /dev/null +++ b/plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +extern char imx8mp_rotpk_hash[], imx8mp_rotpk_hash_end[]; + +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + *key_ptr = imx8mp_rotpk_hash; + *key_len = imx8mp_rotpk_hash_end - imx8mp_rotpk_hash; + *flags = ROTPK_IS_HASH; + + return 0; +} + +int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) +{ + *nv_ctr = 0; + + return 0; +} + +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + return 1; +} + +int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + return get_mbedtls_heap_helper(heap_addr, heap_size); +} diff --git a/plat/imx/imx8m/imx8mp/platform.mk b/plat/imx/imx8m/imx8mp/platform.mk index f134f3384..823b5d6d4 100644 --- a/plat/imx/imx8m/imx8mp/platform.mk +++ b/plat/imx/imx8m/imx8mp/platform.mk @@ -94,6 +94,44 @@ LOAD_IMAGE_V2 := 1 BL2_AT_EL3 := 1 endif +ifneq (${TRUSTED_BOARD_BOOT},0) + +include drivers/auth/mbedtls/mbedtls_crypto.mk +include drivers/auth/mbedtls/mbedtls_x509.mk + +AUTH_SOURCES := drivers/auth/auth_mod.c \ + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c \ + drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c + +BL2_SOURCES += ${AUTH_SOURCES} \ + plat/common/tbbr/plat_tbbr.c \ + plat/imx/imx8m/imx8mp/imx8mp_trusted_boot.c \ + plat/imx/imx8m/imx8mp/imx8mp_rotpk.S + +ROT_KEY = $(BUILD_PLAT)/rot_key.pem +ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin + +$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"')) +$(eval $(call MAKE_LIB_DIRS)) + +$(BUILD_PLAT)/bl2/imx8mp_rotpk.o: $(ROTPK_HASH) + +certificates: $(ROT_KEY) + +$(ROT_KEY): | $(BUILD_PLAT) + @echo " OPENSSL $@" + @if [ ! -f $(ROT_KEY) ]; then \ + openssl genrsa 2048 > $@ 2>/dev/null; \ + fi + +$(ROTPK_HASH): $(ROT_KEY) + @echo " OPENSSL $@" + $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\ + openssl dgst -sha256 -binary > $@ 2>/dev/null +endif + USE_COHERENT_MEM := 1 RESET_TO_BL31 := 1 A53_DISABLE_NON_TEMPORAL_HINT := 0 -- cgit v1.2.3 From 75edd34ade8efaa8a76c5fd59103454023632989 Mon Sep 17 00:00:00 2001 From: Penny Jan Date: Thu, 19 Aug 2021 15:34:43 +0800 Subject: feat(plat/mediatek/mt8195): add EMI MPU basic drivers EMI MPU stands for external memory interface memory protect unit. MT8195 supports 32 regions and 16 domains. We add basic drivers currently, and will add more setting for EMI MPU in next patch. Change-Id: Iedc19d8f6fcf1ceb2d8241319b8dc17c885642dd Signed-off-by: Penny Jan --- plat/mediatek/mt8195/bl31_plat_setup.c | 4 ++ plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c | 97 +++++++++++++++++++++++++ plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h | 98 ++++++++++++++++++++++++++ plat/mediatek/mt8195/include/platform_def.h | 6 ++ plat/mediatek/mt8195/platform.mk | 2 + 5 files changed, 207 insertions(+) create mode 100644 plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c create mode 100644 plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h diff --git a/plat/mediatek/mt8195/bl31_plat_setup.c b/plat/mediatek/mt8195/bl31_plat_setup.c index 8745454b7..dff66709e 100644 --- a/plat/mediatek/mt8195/bl31_plat_setup.c +++ b/plat/mediatek/mt8195/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include /* Platform Includes */ +#include #include #include #include @@ -90,6 +91,9 @@ void bl31_platform_setup(void) ERROR("Failed to set default dcm on!!\n"); } + /* Initialize EMI MPU */ + emi_mpu_init(); + /* Initialize the GIC driver, CPU and distributor interfaces */ mt_gic_driver_init(); mt_gic_init(); diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c new file mode 100644 index 000000000..4330b77d5 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#if ENABLE_EMI_MPU_SW_LOCK +static unsigned char region_lock_state[EMI_MPU_REGION_NUM]; +#endif + +#define EMI_MPU_START_MASK (0x00FFFFFF) +#define EMI_MPU_END_MASK (0x00FFFFFF) +#define EMI_MPU_APC_SW_LOCK_MASK (0x00FFFFFF) +#define EMI_MPU_APC_HW_LOCK_MASK (0x80FFFFFF) + +static int _emi_mpu_set_protection(unsigned int start, unsigned int end, + unsigned int apc) +{ + unsigned int dgroup; + unsigned int region; + + region = (start >> 24) & 0xFF; + start &= EMI_MPU_START_MASK; + dgroup = (end >> 24) & 0xFF; + end &= EMI_MPU_END_MASK; + + if ((region >= EMI_MPU_REGION_NUM) || (dgroup > EMI_MPU_DGROUP_NUM)) { + WARN("invalid region, domain\n"); + return -1; + } + +#if ENABLE_EMI_MPU_SW_LOCK + if (region_lock_state[region] == 1) { + WARN("invalid region\n"); + return -1; + } + + if ((dgroup == 0) && ((apc >> 31) & 0x1)) { + region_lock_state[region] = 1; + } + + apc &= EMI_MPU_APC_SW_LOCK_MASK; +#else + apc &= EMI_MPU_APC_HW_LOCK_MASK; +#endif + + if ((start >= DRAM_OFFSET) && (end >= start)) { + start -= DRAM_OFFSET; + end -= DRAM_OFFSET; + } else { + WARN("invalid range\n"); + return -1; + } + + mmio_write_32(EMI_MPU_SA(region), start); + mmio_write_32(EMI_MPU_EA(region), end); + mmio_write_32(EMI_MPU_APC(region, dgroup), apc); + +#if defined(SUB_EMI_MPU_BASE) + mmio_write_32(SUB_EMI_MPU_SA(region), start); + mmio_write_32(SUB_EMI_MPU_EA(region), end); + mmio_write_32(SUB_EMI_MPU_APC(region, dgroup), apc); +#endif + return 1; +} + +int emi_mpu_set_protection(struct emi_region_info_t *region_info) +{ + unsigned int start, end; + int i; + + if (region_info->region >= EMI_MPU_REGION_NUM) { + WARN("invalid region\n"); + return -1; + } + + start = (unsigned int)(region_info->start >> EMI_MPU_ALIGN_BITS) | + (region_info->region << 24); + + for (i = EMI_MPU_DGROUP_NUM - 1; i >= 0; i--) { + end = (unsigned int)(region_info->end >> EMI_MPU_ALIGN_BITS) | + (i << 24); + _emi_mpu_set_protection(start, end, region_info->apc[i]); + } + + return 0; +} + +void emi_mpu_init(void) +{ + /* TODO: more setting for EMI MPU. */ +} diff --git a/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h new file mode 100644 index 000000000..415146ece --- /dev/null +++ b/plat/mediatek/mt8195/drivers/emi_mpu/emi_mpu.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EMI_MPU_H +#define EMI_MPU_H + +#include + +#define ENABLE_EMI_MPU_SW_LOCK 1 + +#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x000) +#define EMI_MPU_DBG (EMI_MPU_BASE + 0x004) +#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100) +#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200) +#define EMI_MPU_SA(region) (EMI_MPU_SA0 + (region * 4)) +#define EMI_MPU_EA(region) (EMI_MPU_EA0 + (region * 4)) +#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300) +#define EMI_MPU_APC(region, dgroup) (EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100)) +#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800) +#define EMI_MPU_CTRL_D(domain) (EMI_MPU_CTRL_D0 + (domain * 4)) +#define EMI_RG_MASK_D0 (EMI_MPU_BASE + 0x900) +#define EMI_RG_MASK_D(domain) (EMI_RG_MASK_D0 + (domain * 4)) +#define EMI_MPU_START (0x000) +#define EMI_MPU_END (0x93C) + +#define SUB_EMI_MPU_CTRL (SUB_EMI_MPU_BASE + 0x000) +#define SUB_EMI_MPU_DBG (SUB_EMI_MPU_BASE + 0x004) +#define SUB_EMI_MPU_SA0 (SUB_EMI_MPU_BASE + 0x100) +#define SUB_EMI_MPU_EA0 (SUB_EMI_MPU_BASE + 0x200) +#define SUB_EMI_MPU_SA(region) (SUB_EMI_MPU_SA0 + (region * 4)) +#define SUB_EMI_MPU_EA(region) (SUB_EMI_MPU_EA0 + (region * 4)) +#define SUB_EMI_MPU_APC0 (SUB_EMI_MPU_BASE + 0x300) +#define SUB_EMI_MPU_APC(region, dgroup) (SUB_EMI_MPU_APC0 + (region * 4) + (dgroup * 0x100)) +#define SUB_EMI_MPU_CTRL_D0 (SUB_EMI_MPU_BASE + 0x800) +#define SUB_EMI_MPU_CTRL_D(domain) (SUB_EMI_MPU_CTRL_D0 + (domain * 4)) +#define SUB_EMI_RG_MASK_D0 (SUB_EMI_MPU_BASE + 0x900) +#define SUB_EMI_RG_MASK_D(domain) (SUB_EMI_RG_MASK_D0 + (domain * 4)) + +#define EMI_MPU_DOMAIN_NUM (16) +#define EMI_MPU_REGION_NUM (32) +#define EMI_MPU_ALIGN_BITS (16) +#define DRAM_OFFSET (0x40000000 >> EMI_MPU_ALIGN_BITS) + +#define NO_PROTECTION 0 +#define SEC_RW 1 +#define SEC_RW_NSEC_R 2 +#define SEC_RW_NSEC_W 3 +#define SEC_R_NSEC_R 4 +#define FORBIDDEN 5 +#define SEC_R_NSEC_RW 6 + +#define LOCK 1 +#define UNLOCK 0 + +#define EMI_MPU_DGROUP_NUM (EMI_MPU_DOMAIN_NUM / 8) + +#if (EMI_MPU_DGROUP_NUM == 1) +#define SET_ACCESS_PERMISSION(apc_ary, lock, d7, d6, d5, d4, d3, d2, d1, d0) \ +do { \ + apc_ary[1] = 0; \ + apc_ary[0] = \ + (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \ + (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \ + (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \ + (((unsigned int) d1) << 3) | ((unsigned int) d0) | \ + ((unsigned int) lock << 31); \ +} while (0) +#elif (EMI_MPU_DGROUP_NUM == 2) +#define SET_ACCESS_PERMISSION(apc_ary, lock, d15, d14, d13, d12, d11, d10, \ + d9, d8, d7, d6, d5, d4, d3, d2, d1, d0) \ +do { \ + apc_ary[1] = \ + (((unsigned int) d15) << 21) | (((unsigned int) d14) << 18) | \ + (((unsigned int) d13) << 15) | (((unsigned int) d12) << 12) | \ + (((unsigned int) d11) << 9) | (((unsigned int) d10) << 6) | \ + (((unsigned int) d9) << 3) | ((unsigned int) d8); \ + apc_ary[0] = \ + (((unsigned int) d7) << 21) | (((unsigned int) d6) << 18) | \ + (((unsigned int) d5) << 15) | (((unsigned int) d4) << 12) | \ + (((unsigned int) d3) << 9) | (((unsigned int) d2) << 6) | \ + (((unsigned int) d1) << 3) | ((unsigned int) d0) | \ + ((unsigned int) lock << 31); \ +} while (0) +#endif + +struct emi_region_info_t { + unsigned long long start; + unsigned long long end; + unsigned int region; + unsigned int apc[EMI_MPU_DGROUP_NUM]; +}; + +void emi_mpu_init(void); + +#endif diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h index a28733394..44de8eb3b 100644 --- a/plat/mediatek/mt8195/include/platform_def.h +++ b/plat/mediatek/mt8195/include/platform_def.h @@ -65,6 +65,12 @@ ******************************************************************************/ #define PMIC_WRAP_BASE (IO_PHYS + 0x00024000) +/******************************************************************************* + * EMI MPU related constants + ******************************************************************************/ +#define EMI_MPU_BASE (IO_PHYS + 0x00226000) +#define SUB_EMI_MPU_BASE (IO_PHYS + 0x00225000) + /******************************************************************************* * System counter frequency related constants ******************************************************************************/ diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk index f4604c434..48a2f72e3 100644 --- a/plat/mediatek/mt8195/platform.mk +++ b/plat/mediatek/mt8195/platform.mk @@ -16,6 +16,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT}/common/lpm/ \ -I${MTK_PLAT_SOC}/drivers/dcm \ -I${MTK_PLAT_SOC}/drivers/dp/ \ + -I${MTK_PLAT_SOC}/drivers/emi_mpu/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ -I${MTK_PLAT_SOC}/drivers/pmic/ \ @@ -60,6 +61,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \ ${MTK_PLAT_SOC}/drivers/dp/mt_dp.c \ + ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \ -- cgit v1.2.3 From 6cad59c429b4382ad62aee3a67fa1b3fd4ad38b7 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 15:36:37 +0800 Subject: feat(plat/nxp/common): add CCI and EPU address definition Add CCI and EPU base address definiton for Chassis v3.2. Signed-off-by: Jiafei Pan Change-Id: I13250555b6646c1e7ba2e9d7c9efca8501f17b3a --- plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h index 08300b055..0a4228b7e 100644 --- a/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h +++ b/plat/nxp/common/include/default/ch_3_2/soc_default_base_addr.h @@ -23,6 +23,9 @@ /* MMU 500 soc.c*/ #define NXP_SMMU_ADDR 0x05000000 +/* CCI400 base address */ +#define NXP_CCI_ADDR 0x04090000 + #define NXP_SNVS_ADDR 0x01E90000 #define NXP_DCFG_ADDR 0x01E00000 @@ -81,4 +84,5 @@ #define NXP_CCN_HNI_ADDR 0x04080000 #define NXP_CCN_HN_F_0_ADDR 0x04200000 +#define NXP_EPU_ADDR 0x700060000 #endif /* SOC_DEFAULT_BASE_ADDR_H */ -- cgit v1.2.3 From 35efe7a4cea4b3c55b661aac49ef1a85ca8feaa9 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 18:54:56 +0800 Subject: feat(plat/nxp/common): define common macro for ARM registers Define common register macro both for Cortex-A53 and Cortex-A72 because the code will be used by both Cortex platform. Signed-off-by: Biwen Li Signed-off-by: Jiafei Pan Change-Id: I485661bfe3ed4f214c403ff6af53dc6af1ddf089 --- plat/nxp/common/psci/aarch64/psci_utils.S | 24 ++++++++++++------------ plat/nxp/common/psci/include/plat_psci.h | 4 +++- plat/nxp/common/setup/core.mk | 6 ++++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/plat/nxp/common/psci/aarch64/psci_utils.S b/plat/nxp/common/psci/aarch64/psci_utils.S index ea2abbfb5..ec69aea03 100644 --- a/plat/nxp/common/psci/aarch64/psci_utils.S +++ b/plat/nxp/common/psci/aarch64/psci_utils.S @@ -1,6 +1,6 @@ /* - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * SPDX-License-Identifier: BSD-3-Clause * @@ -234,7 +234,7 @@ func _psci_cpu_prep_off msr DAIFSet, #0xF /* read cpuectlr and save current value */ - mrs x4, CORTEX_A72_ECTLR_EL1 + mrs x4, CPUECTLR_EL1 mov x1, #CPUECTLR_DATA mov x2, x4 mov x0, x10 @@ -242,7 +242,7 @@ func _psci_cpu_prep_off /* remove the core from coherency */ bic x4, x4, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x4 + msr CPUECTLR_EL1, x4 /* save scr_el3 */ mov x0, x10 @@ -339,7 +339,7 @@ func _psci_wakeup mov x1, #CPUECTLR_DATA bl _getCoreData orr x0, x0, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x0 + msr CPUECTLR_EL1, x0 /* x4 = core mask */ @@ -563,7 +563,7 @@ func _psci_core_prep_pwrdn /* save cpuectlr */ mov x0, x6 mov x1, #CPUECTLR_DATA - mrs x2, CORTEX_A72_ECTLR_EL1 + mrs x2, CPUECTLR_EL1 bl _setCoreData /* x6 = core mask */ @@ -640,7 +640,7 @@ func _psci_core_exit_pwrdn bl _getCoreData /* make sure smp is set */ orr x0, x0, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x0 + msr CPUECTLR_EL1, x0 /* x5 = core mask */ @@ -780,13 +780,13 @@ func _psci_clstr_prep_pwrdn /* save cpuectlr */ mov x0, x6 mov x1, #CPUECTLR_DATA - mrs x2, CORTEX_A72_ECTLR_EL1 + mrs x2, CPUECTLR_EL1 mov x4, x2 bl _setCoreData /* remove core from coherency */ bic x4, x4, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x4 + msr CPUECTLR_EL1, x4 /* x6 = core mask */ @@ -844,7 +844,7 @@ func _psci_clstr_exit_pwrdn bl _getCoreData /* make sure smp is set */ orr x0, x0, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x0 + msr CPUECTLR_EL1, x0 /* x4 = core mask */ @@ -985,13 +985,13 @@ func _psci_sys_prep_pwrdn /* save cpuectlr */ mov x0, x6 mov x1, #CPUECTLR_DATA - mrs x2, CORTEX_A72_ECTLR_EL1 + mrs x2, CPUECTLR_EL1 mov x4, x2 bl _setCoreData /* remove core from coherency */ bic x4, x4, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x4 + msr CPUECTLR_EL1, x4 /* x6 = core mask */ @@ -1071,7 +1071,7 @@ func _psci_sys_exit_pwrdn /* make sure smp is set */ orr x0, x0, #CPUECTLR_SMPEN_MASK - msr CORTEX_A72_ECTLR_EL1, x0 + msr CPUECTLR_EL1, x0 /* x4 = core mask */ diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h index 97d4c97eb..c81340c95 100644 --- a/plat/nxp/common/psci/include/plat_psci.h +++ b/plat/nxp/common/psci/include/plat_psci.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 NXP + * Copyright 2018-2021 NXP * * SPDX-License-Identifier: BSD-3-Clause * @@ -7,6 +7,8 @@ #ifndef PLAT_PSCI_H #define PLAT_PSCI_H +#include +#include /* core abort current op */ #define CORE_ABORT_OP 0x1 diff --git a/plat/nxp/common/setup/core.mk b/plat/nxp/common/setup/core.mk index 9b81f2d46..82ce30ecd 100644 --- a/plat/nxp/common/setup/core.mk +++ b/plat/nxp/common/setup/core.mk @@ -1,4 +1,4 @@ -# Copyright 2018-2020 NXP +# Copyright 2018-2021 NXP # # SPDX-License-Identifier: BSD-3-Clause # @@ -11,9 +11,11 @@ CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S -ifeq (,$(filter $(CORE_TYPE),a53 a55 a57 a72 a75)) +ifeq (,$(filter $(CORE_TYPE),a53 a72)) $(error "CORE_TYPE not specified or incorrect") else +UPPER_CORE_TYPE=$(shell echo $(CORE_TYPE) | tr a-z A-Z) +$(eval $(call add_define_val,CPUECTLR_EL1,CORTEX_$(UPPER_CORE_TYPE)_ECTLR_EL1)) CPU_LIBS += lib/cpus/${ARCH}/cortex_$(CORE_TYPE).S endif -- cgit v1.2.3 From a2047853224083328ef67cacbc17a2001ba14701 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:01:15 +0800 Subject: feat(plat/nxp/common): define default PSCI features if not defined SoC code can define supported features, otherwise use default setting. Signed-off-by: Biwen Li Signed-off-by: Jiafei Pan Change-Id: I0f11498c1f7558ff0ec2d9b344f3f7a4f5489ced --- plat/nxp/common/psci/include/plat_psci.h | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h index c81340c95..45958b1c2 100644 --- a/plat/nxp/common/psci/include/plat_psci.h +++ b/plat/nxp/common/psci/include/plat_psci.h @@ -64,18 +64,53 @@ * value == 0x0, the soc code does not support this feature * value != 0x0, the soc code supports this feature */ +#ifndef SOC_CORE_RELEASE #define SOC_CORE_RELEASE 0x1 +#endif + +#ifndef SOC_CORE_RESTART #define SOC_CORE_RESTART 0x1 +#endif + +#ifndef SOC_CORE_OFF #define SOC_CORE_OFF 0x1 +#endif + +#ifndef SOC_CORE_STANDBY #define SOC_CORE_STANDBY 0x1 +#endif + +#ifndef SOC_CORE_PWR_DWN #define SOC_CORE_PWR_DWN 0x1 +#endif + +#ifndef SOC_CLUSTER_STANDBY #define SOC_CLUSTER_STANDBY 0x1 +#endif + +#ifndef SOC_CLUSTER_PWR_DWN #define SOC_CLUSTER_PWR_DWN 0x1 +#endif + +#ifndef SOC_SYSTEM_STANDBY #define SOC_SYSTEM_STANDBY 0x1 +#endif + +#ifndef SOC_SYSTEM_PWR_DWN #define SOC_SYSTEM_PWR_DWN 0x1 +#endif + +#ifndef SOC_SYSTEM_OFF #define SOC_SYSTEM_OFF 0x1 +#endif + +#ifndef SOC_SYSTEM_RESET #define SOC_SYSTEM_RESET 0x1 +#endif + +#ifndef SOC_SYSTEM_RESET2 #define SOC_SYSTEM_RESET2 0x1 +#endif #ifndef __ASSEMBLER__ -- cgit v1.2.3 From 3a2cc2e262890cffee1fc46835e85be6055189e8 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:08:19 +0800 Subject: feat(plat/nxp/common/psci): define CPUECTLR_TIMER_2TICKS Define CPUECTLR_TIMER_2TICKS. Signed-off-by: Yangbo Lu Signed-off-by: Jiafei Pan Change-Id: Iecb5ede82939e8502d2f1bc74ec3bfe2a00be65c --- plat/nxp/common/psci/include/plat_psci.h | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/nxp/common/psci/include/plat_psci.h b/plat/nxp/common/psci/include/plat_psci.h index 45958b1c2..7fc48fb73 100644 --- a/plat/nxp/common/psci/include/plat_psci.h +++ b/plat/nxp/common/psci/include/plat_psci.h @@ -57,6 +57,7 @@ #define CPUECTLR_RET_SET 0x2 #define CPUECTLR_TIMER_MASK 0x7 #define CPUECTLR_TIMER_8TICKS 0x2 +#define CPUECTLR_TIMER_2TICKS 0x1 #define SCR_IRQ_MASK 0x2 #define SCR_FIQ_MASK 0x4 -- cgit v1.2.3 From 6c5d140ed99cfec47b239acc242c0f3db1e3bf7c Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:10:47 +0800 Subject: feat(driver/nxp/dcfg): define RSTCR_RESET_REQ Define RSTCR_RESET_REQ for Chassis V3. Signed-off-by: Biwen Li Signed-off-by: Jiafei Pan Change-Id: I5cb7019baae5fe0d06b3d5e65f185f87ee16ad3a --- include/drivers/nxp/dcfg/dcfg_lsch3.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/drivers/nxp/dcfg/dcfg_lsch3.h b/include/drivers/nxp/dcfg/dcfg_lsch3.h index 40f02c190..cde86fe19 100644 --- a/include/drivers/nxp/dcfg/dcfg_lsch3.h +++ b/include/drivers/nxp/dcfg/dcfg_lsch3.h @@ -74,4 +74,7 @@ #define DCFG_BOOTLOCPTRH_OFFSET 0x404 #define DCFG_COREDISABLEDSR_OFFSET 0x990 +/* Reset module bit field */ +#define RSTCR_RESET_REQ 0x2 + #endif /* DCFG_LSCH3_H */ -- cgit v1.2.3 From 66f7884b5229b1d2977d73d105af1c34cb55f95d Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:13:27 +0800 Subject: feat(plat/nxp/common): add SecMon register definition for ch_3_2 Add SecMon register definition for ch_3_2. Signed-off-by: Yangbo Lu Signed-off-by: Jiafei Pan Change-Id: I80d134ea4e94ad234e1a8fbd02798d5fd86d2544 --- plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h index cdc823a22..8de516efc 100644 --- a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h +++ b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h @@ -39,6 +39,10 @@ #endif /* NXP_RESET_ADDR */ +/* secmon register offsets and bitfields */ +#define SECMON_HPCOMR_OFFSET 0x4 +#define SECMON_HPCOMR_NPSWAEN 0x80000000 + /* Secure-Register-File register offsets and bit masks */ #ifdef NXP_RST_ADDR /* Register Offset */ -- cgit v1.2.3 From a4f5015a0080134251e9272719f5dad1ce2aa842 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:15:15 +0800 Subject: feat(driver/nxp/xspi): add MT35XU02G flash info Add MT35XU02G flash info. Signed-off-by: Yangbo Lu Signed-off-by: Jiafei Pan Change-Id: I2dbbdcb454fae4befef71769f9646c077d72a057 --- include/drivers/nxp/flexspi/flash_info.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/include/drivers/nxp/flexspi/flash_info.h b/include/drivers/nxp/flexspi/flash_info.h index 6df79c961..94c9f027c 100644 --- a/include/drivers/nxp/flexspi/flash_info.h +++ b/include/drivers/nxp/flexspi/flash_info.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD-3-Clause /* - * Copyright 2020 NXP + * Copyright 2020-2021 NXP */ /** @@ -53,6 +53,16 @@ #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif +#elif defined(CONFIG_MT35XU02G) +#define F_SECTOR_128K 0x20000U +#define F_PAGE_256 0x100U +#define F_SECTOR_4K 0x1000U +#define F_FLASH_SIZE_BYTES 0x10000000U +#define F_SECTOR_ERASE_SZ F_SECTOR_128K +#ifdef CONFIG_FSPI_4K_ERASE +#define F_SECTOR_ERASE_SZ F_SECTOR_4K +#endif + #ifdef NXP_WARM_BOOT #define FLASH_WR_COMP_WAIT_BY_NOP_COUNT 0x20000 #endif -- cgit v1.2.3 From 4225ce8b87635287ecf5cd3baaf31ea703a2640b Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 19:19:32 +0800 Subject: feat(plat/nxp/common): define default SD buffer Define default SD buffer address and size in DRAM. Signed-off-by: Biwen Li Signed-off-by: Jiafei Pan Change-Id: I5872d95b0c1114e05f0e145756e9a6ef39b2fd9a --- plat/nxp/common/include/default/plat_default_def.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plat/nxp/common/include/default/plat_default_def.h b/plat/nxp/common/include/default/plat_default_def.h index dd5dfe005..43320bb4b 100644 --- a/plat/nxp/common/include/default/plat_default_def.h +++ b/plat/nxp/common/include/default/plat_default_def.h @@ -40,8 +40,12 @@ #define NXP_NS_DRAM_ADDR NXP_DRAM0_ADDR #endif -/* 64M is reserved for Secure memory - */ +/* 1 MB is reserved for dma of sd */ +#ifndef NXP_SD_BLOCK_BUF_SIZE +#define NXP_SD_BLOCK_BUF_SIZE (1 * 1024 * 1024) +#endif + +/* 64MB is reserved for Secure memory */ #ifndef NXP_SECURE_DRAM_SIZE #define NXP_SECURE_DRAM_SIZE (64 * 1024 * 1024) #endif @@ -57,18 +61,22 @@ (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) #endif +#ifndef NXP_SD_BLOCK_BUF_ADDR +#define NXP_SD_BLOCK_BUF_ADDR (NXP_NS_DRAM_ADDR) +#endif + #ifndef NXP_SECURE_DRAM_ADDR #ifdef TEST_BL31 #define NXP_SECURE_DRAM_ADDR 0 #else #define NXP_SECURE_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \ - (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) + (NXP_SECURE_DRAM_SIZE + NXP_SP_SHRD_DRAM_SIZE)) #endif #endif #ifndef NXP_SP_SHRD_DRAM_ADDR -#define NXP_SP_SHRD_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE \ - - NXP_SP_SHRD_DRAM_SIZE) +#define NXP_SP_SHRD_DRAM_ADDR (NXP_NS_DRAM_ADDR + PLAT_DEF_DRAM0_SIZE - \ + NXP_SP_SHRD_DRAM_SIZE) #endif #ifndef BL31_BASE -- cgit v1.2.3 From ef378d3ec1ef9d7c28baef32ed409688e962542b Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 29 Apr 2021 22:32:10 +0300 Subject: fix(drivers/tzc400): never disable filter 0 Disabling filter 0 causes inability to access DRAM. An attempt leads to an abort. ARM manual disallows to disable filter 0, but if we do that from SRAM, nothing bad happens. This patch prevents disabling of a filter 0, allowing to reconfigure other filters from DRAM. Note: this patch doesn't change the logic after reset. It is only needed in case someone wants to reconfigure the previously configured TZASC. Change-Id: I196a0cb110a89afbde97f64a94df3101f28708a4 Signed-off-by: stsp@users.sourceforge.net --- drivers/arm/tzc/tzc400.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/arm/tzc/tzc400.c b/drivers/arm/tzc/tzc400.c index f1dacbbbd..e4fc8c927 100644 --- a/drivers/arm/tzc/tzc400.c +++ b/drivers/arm/tzc/tzc400.c @@ -291,6 +291,11 @@ void tzc400_enable_filters(void) for (filter = 0U; filter < tzc400.num_filters; filter++) { state = _tzc400_get_gate_keeper(tzc400.base, filter); if (state != 0U) { + /* Filter 0 is special and cannot be disabled. + * So here we allow it being already enabled. */ + if (filter == 0U) { + continue; + } /* * The TZC filter is already configured. Changing the * programmer's view in an active system can cause @@ -312,14 +317,17 @@ void tzc400_enable_filters(void) void tzc400_disable_filters(void) { unsigned int filter; + unsigned int state; + unsigned int start = 0U; assert(tzc400.base != 0U); - /* - * We don't do the same state check as above as the Gatekeepers are - * disabled after reset. - */ - for (filter = 0; filter < tzc400.num_filters; filter++) + /* Filter 0 is special and cannot be disabled. */ + state = _tzc400_get_gate_keeper(tzc400.base, 0); + if (state != 0U) { + start++; + } + for (filter = start; filter < tzc400.num_filters; filter++) _tzc400_set_gate_keeper(tzc400.base, filter, 0); } -- cgit v1.2.3 From 38f79045775cb4c53348b9ca4899309ebfa51d08 Mon Sep 17 00:00:00 2001 From: Davidson K Date: Tue, 10 Aug 2021 19:25:57 +0530 Subject: refactor(tc): use internal trusted storage Trusted Services had removed secure storage and added two new trusted services - Protected Storage and Internal Trusted Storage. Hence we are removing secure storage and adding support for the internal trusted storage. And enable external SP images in BL2 config for TC, so that we do not have to modify this file whenever the list of SPs changes. It is already implemented for fvp in the below commit. commit 33993a3737737a03ee5a9d386d0a027bdc947c9c Author: Balint Dobszay Date: Fri Mar 26 15:19:11 2021 +0100 feat(fvp): enable external SP images in BL2 config Change-Id: I3e0a0973df3644413ca5c3a32f36d44c8efd49c7 Signed-off-by: Davidson K --- docs/plat/arm/arm-build-options.rst | 2 +- plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts | 2 +- plat/arm/board/tc/fdts/tc_tb_fw_config.dts | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index 74251bd28..339ebbe33 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -108,7 +108,7 @@ Arm Platform Build Options file name contains pattern optee_sp. - ``TS_SP_FW_CONFIG``: DTC build flag to include Trusted Services (Crypto and - secure-storage) as SP in tb_fw_config device tree. + internal-trusted-storage) as SP in tb_fw_config device tree. - ``ARM_GPT_SUPPORT``: Enable GPT parser to get the entry address and length of the various partitions present in the GPT image. This support is available diff --git a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts index 34b4e74c3..92e2ddda6 100644 --- a/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts +++ b/plat/arm/board/tc/fdts/tc_spmc_optee_sp_manifest.dts @@ -36,7 +36,7 @@ #ifdef TS_SP_FW_CONFIG vm2 { is_ffa_partition; - debug_name = "secure-storage"; + debug_name = "internal-trusted-storage"; load_address = <0xfee00000>; vcpu_count = <1>; mem_size = <2097152>; /* 2MB TZC DRAM */ diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts index 28ed7ae94..af80550db 100644 --- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts +++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include + /dts-v1/; / { @@ -27,8 +29,11 @@ secure-partitions { compatible = "arm,sp"; +#ifdef ARM_BL2_SP_LIST_DTS + #include __XSTRING(ARM_BL2_SP_LIST_DTS) +#else #ifdef TS_SP_FW_CONFIG - secure-storage { + internal-trusted-storage { uuid = "dc1eef48-b17a-4ccf-ac8b-dfcff7711b14"; load-address = <0xfee00000>; }; @@ -60,5 +65,6 @@ load-address = <0xfe200000>; }; #endif +#endif /* ARM_BL2_SP_LIST_DTS */ }; }; -- cgit v1.2.3 From fc3f480023e3a52460add25f18dd550dde44d9ff Mon Sep 17 00:00:00 2001 From: J-Alves Date: Thu, 11 Mar 2021 17:46:47 +0000 Subject: feat(ff-a): adding notifications SMC IDs Defining SMC IDs for FF-A v1.1 notifications functionality, and adding them to SPMD SMC handler, to ensure calls are forwarded to the SPMC. Signed-off-by: J-Alves Change-Id: Icc88aded0fd33507f7795e996bd4ff1c2fe679c8 --- include/services/ffa_svc.h | 12 ++++++++++++ services/std_svc/spmd/spmd_main.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index ab36d9e1f..85ff703bc 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -128,6 +128,16 @@ #define FFA_MEM_RETRIEVE_RESP FFA_FID(SMC_32, FFA_FNUM_MEM_RETRIEVE_RESP) #define FFA_MEM_RELINQUISH FFA_FID(SMC_32, FFA_FNUM_MEM_RELINQUISH) #define FFA_MEM_RECLAIM FFA_FID(SMC_32, FFA_FNUM_MEM_RECLAIM) +#define FFA_NOTIFICATION_BITMAP_CREATE \ + FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_CREATE) +#define FFA_NOTIFICATION_BITMAP_DESTROY \ + FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BITMAP_DESTROY) +#define FFA_NOTIFICATION_BIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_BIND) +#define FFA_NOTIFICATION_UNBIND FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_UNBIND) +#define FFA_NOTIFICATION_SET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_SET) +#define FFA_NOTIFICATION_GET FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_GET) +#define FFA_NOTIFICATION_INFO_GET \ + FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET) #define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET) /* FFA SMC64 FIDs */ @@ -145,6 +155,8 @@ FFA_FID(SMC_64, FFA_FNUM_MEM_RETRIEVE_REQ) #define FFA_SECONDARY_EP_REGISTER_SMC64 \ FFA_FID(SMC_64, FFA_FNUM_SECONDARY_EP_REGISTER) +#define FFA_NOTIFICATION_INFO_GET_SMC64 \ + FFA_FID(SMC_64, FFA_FNUM_NOTIFICATION_INFO_GET) /* * Reserve a special value for traffic targeted to the Hypervisor or SPM. diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index dda127fd4..67fca188a 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -620,9 +620,19 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, case FFA_RXTX_MAP_SMC64: case FFA_RXTX_UNMAP: case FFA_PARTITION_INFO_GET: +#if MAKE_FFA_VERSION(1, 1) <= FFA_VERSION_COMPILED + case FFA_NOTIFICATION_BITMAP_CREATE: + case FFA_NOTIFICATION_BITMAP_DESTROY: + case FFA_NOTIFICATION_BIND: + case FFA_NOTIFICATION_UNBIND: + case FFA_NOTIFICATION_SET: + case FFA_NOTIFICATION_GET: + case FFA_NOTIFICATION_INFO_GET: + case FFA_NOTIFICATION_INFO_GET_SMC64: +#endif /* - * Should not be allowed to forward FFA_PARTITION_INFO_GET - * from Secure world to Normal world + * Above calls should not be forwarded from Secure world to + * Normal world. * * Fall through to forward the call to the other world */ -- cgit v1.2.3 From 85e4d14df157b5641421ea2b844c146ddc230152 Mon Sep 17 00:00:00 2001 From: Rex-BC Chen Date: Fri, 17 Sep 2021 09:55:21 +0800 Subject: fix(plat/mediatek/mt8195): fix coverity fail Add break to correct the driver flow. Signed-off-by: Rex-BC Chen Change-Id: Ie20f402d543fbf90172671e007fad30d5dc2ab10 --- plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c index 2a9a78926..6a85b5c88 100644 --- a/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c +++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_vcorefs.c @@ -465,13 +465,17 @@ int spm_vcorefs_get_vcore(unsigned int gear) switch (gear) { case 3: ret_val = vcore_opp_0_uv; + break; case 2: ret_val = vcore_opp_1_uv; + break; case 1: ret_val = vcore_opp_2_uv; + break; case 0: default: ret_val = vcore_opp_3_uv; + break; } return ret_val; } -- cgit v1.2.3 From bc453ab1b2fd4267d34f2b9587f73b8940ee1538 Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 18 Jun 2021 15:09:37 +0200 Subject: fix(spi_nand): check that parameters have been set This patch checks that the SPI NAND parameters needed by the framework have been set before starting to read data. Change-Id: I17b36606701c44864dcf1783f810da5c8cbf88f2 Signed-off-by: Christophe Kerello Signed-off-by: Yann Gautier --- drivers/mtd/nand/spi_nand.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c index d01a11963..e7f71c840 100644 --- a/drivers/mtd/nand/spi_nand.c +++ b/drivers/mtd/nand/spi_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -286,6 +286,10 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size) return -EINVAL; } + assert((spinand_dev.nand_dev->page_size != 0U) && + (spinand_dev.nand_dev->block_size != 0U) && + (spinand_dev.nand_dev->size != 0U)); + ret = spi_nand_reset(); if (ret != 0) { return ret; -- cgit v1.2.3 From 4490b7963303fbe59b07a66c8498a803eb5c239c Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Fri, 18 Jun 2021 15:38:40 +0200 Subject: fix(spi_nand): check correct manufacturer id On most of SPI NAND, the read id command needs a dummy byte, except GIGADEVICE SPI NAND that needs an address. To be compliant with all memories providers, the first byte returns by the READ_ID command is not relevant (garbage). Change-Id: Ife74ccab333dd1a04799abe230d3f07fa6ea1edb Signed-off-by: Christophe Kerello Signed-off-by: Yann Gautier --- drivers/mtd/nand/spi_nand.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c index e7f71c840..abb524d7f 100644 --- a/drivers/mtd/nand/spi_nand.c +++ b/drivers/mtd/nand/spi_nand.c @@ -305,12 +305,12 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size) return ret; } - ret = spi_nand_quad_enable(id[0]); + ret = spi_nand_quad_enable(id[1]); if (ret != 0) { return ret; } - VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]); + VERBOSE("SPI_NAND Detected ID 0x%x\n", id[1]); VERBOSE("Page size %i, Block size %i, size %lli\n", spinand_dev.nand_dev->page_size, -- cgit v1.2.3 From 15509093f0ba9a10f97c6f92bc3bb9fcf79a48ce Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 6 Apr 2021 13:41:19 +0200 Subject: fix(stm32mp1_clk): correctly manage RTC clock source The clksrc value contains the RCC register address and the clock source number. When applying the clock source, we should filter out the RCC register address from the given value. Signed-off-by: Yann Gautier Change-Id: I4345b03de7b9afd1df78df4131431cf1eb43ec17 --- drivers/st/clk/stm32mp1_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 6ada96a52..dbe2b8354 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1652,7 +1652,7 @@ static void stm32mp1_set_rtcsrc(unsigned int clksrc, bool lse_css) (clksrc != (uint32_t)CLK_RTC_DISABLED)) { mmio_clrsetbits_32(address, RCC_BDCR_RTCSRC_MASK, - clksrc << RCC_BDCR_RTCSRC_SHIFT); + (clksrc & RCC_SELR_SRC_MASK) << RCC_BDCR_RTCSRC_SHIFT); mmio_setbits_32(address, RCC_BDCR_RTCCKEN); } -- cgit v1.2.3 From cbd2e8a6afdd05c4b404d7998134a3f60cc15518 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Tue, 27 Jul 2021 15:39:16 +0200 Subject: fix(stm32mp1_clk): fix RTC clock rating When RTC clock source is HSE, the RTCDIV is not taken into account. Change-Id: I1613b638e8932c03f3349adb01e13f5294a3bf5d Signed-off-by: Gabriel Fernandez Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp1_clk.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index dbe2b8354..fcc2f27bd 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -56,6 +56,7 @@ enum stm32mp1_parent_id { _HSI_KER = NB_OSC, _HSE_KER, _HSE_KER_DIV2, + _HSE_RTC, _CSI_KER, _PLL1_P, _PLL1_Q, @@ -125,6 +126,7 @@ static const uint8_t parent_id_clock_id[_PARENT_NB] = { [_HSI_KER] = CK_HSI, [_HSE_KER] = CK_HSE, [_HSE_KER_DIV2] = CK_HSE_DIV2, + [_HSE_RTC] = _UNKNOWN_ID, [_CSI_KER] = CK_CSI, [_PLL1_P] = PLL1_P, [_PLL1_Q] = PLL1_Q, @@ -490,7 +492,7 @@ static const uint8_t per_parents[] = { }; static const uint8_t rtc_parents[] = { - _UNKNOWN_ID, _LSE, _LSI, _HSE + _UNKNOWN_ID, _LSE, _LSI, _HSE_RTC }; static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { @@ -587,6 +589,7 @@ static const char * const stm32mp1_clk_parent_name[_PARENT_NB] __unused = { [_HSI_KER] = "HSI_KER", [_HSE_KER] = "HSE_KER", [_HSE_KER_DIV2] = "HSE_KER_DIV2", + [_HSE_RTC] = "HSE_RTC", [_CSI_KER] = "CSI_KER", [_PLL1_P] = "PLL1_P", [_PLL1_Q] = "PLL1_Q", @@ -969,6 +972,10 @@ static unsigned long get_clock_rate(int p) case _HSE_KER_DIV2: clock = stm32mp1_clk_get_fixed(_HSE) >> 1; break; + case _HSE_RTC: + clock = stm32mp1_clk_get_fixed(_HSE); + clock /= (mmio_read_32(rcc_base + RCC_RTCDIVR) & RCC_DIVR_DIV_MASK) + 1U; + break; case _LSI: clock = stm32mp1_clk_get_fixed(_LSI); break; @@ -2152,6 +2159,7 @@ static void secure_parent_clocks(unsigned long parent_id) case _HSE: case _HSE_KER: case _HSE_KER_DIV2: + case _HSE_RTC: case _LSE: break; -- cgit v1.2.3 From 373f06be4ee1114369b96763481b58885623aea4 Mon Sep 17 00:00:00 2001 From: Lionel Debieve Date: Mon, 2 Sep 2019 18:15:45 +0200 Subject: fix(stm32mp1_clk): keep RTCAPB clock always on Further information such as boot instance are sent over backup registers. In order to guarantee direct access to backup registers in uboot, we will keep the RTC clock enabled. Change-Id: I16572d422bfebbf39190a87db8046df486ce91c8 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp1_clk.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index fcc2f27bd..101aa6b2b 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -2218,6 +2218,7 @@ static void sync_earlyboot_clocks_state(void) DDRC2, DDRC2LP, DDRCAPB, DDRPHYCAPB, DDRPHYCAPBLP, DDRPHYC, DDRPHYCLP, + RTCAPB, TZC1, TZC2, TZPC, STGEN_K, @@ -2226,10 +2227,6 @@ static void sync_earlyboot_clocks_state(void) for (idx = 0U; idx < ARRAY_SIZE(secure_enable); idx++) { stm32mp_clk_enable(secure_enable[idx]); } - - if (!stm32mp_is_single_core()) { - stm32mp1_clk_enable_secure(RTCAPB); - } } int stm32mp1_clk_probe(void) -- cgit v1.2.3 From 288f5cf204300d62d3af30772cd8ccc90ca11fea Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 31 Aug 2021 18:23:13 +0200 Subject: refactor(stm32mp1_clk): update RCC registers file The file is first generated with the peripheral spirit XML file. And then we add some common definition, to ease driver development. Change-Id: I4c222cf006caf27cda6da044eaf184ce66bb1442 Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp1_clk.c | 4 +- include/drivers/st/stm32mp1_rcc.h | 2695 ++++++++++++++++++++++++++++++------- 2 files changed, 2231 insertions(+), 468 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 101aa6b2b..80b6408e4 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -108,7 +108,7 @@ enum stm32mp1_parent_sel { _USBPHY_SEL, _USBO_SEL, _MPU_SEL, - _PER_SEL, + _CKPER_SEL, _RTC_SEL, _PARENT_SEL_NB, _UNKNOWN_SEL = 0xff, @@ -504,7 +504,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(UART1, RCC_UART1CKSELR, usart1_parents), _CLK_PARENT_SEL(RNG1, RCC_RNG1CKSELR, rng1_parents), _CLK_PARENT_SEL(MPU, RCC_MPCKSELR, mpu_parents), - _CLK_PARENT_SEL(PER, RCC_CPERCKSELR, per_parents), + _CLK_PARENT_SEL(CKPER, RCC_CPERCKSELR, per_parents), _CLK_PARENT_SEL(RTC, RCC_BDCR, rtc_parents), _CLK_PARENT_SEL(UART6, RCC_UART6CKSELR, uart6_parents), _CLK_PARENT_SEL(UART24, RCC_UART24CKSELR, uart234578_parents), diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h index 2ffc3b2bc..14f93fdce 100644 --- a/include/drivers/st/stm32mp1_rcc.h +++ b/include/drivers/st/stm32mp1_rcc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2015-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,488 +9,397 @@ #include -#define RCC_TZCR U(0x00) -#define RCC_OCENSETR U(0x0C) -#define RCC_OCENCLRR U(0x10) -#define RCC_HSICFGR U(0x18) -#define RCC_CSICFGR U(0x1C) -#define RCC_MPCKSELR U(0x20) -#define RCC_ASSCKSELR U(0x24) -#define RCC_RCK12SELR U(0x28) -#define RCC_MPCKDIVR U(0x2C) -#define RCC_AXIDIVR U(0x30) -#define RCC_APB4DIVR U(0x3C) -#define RCC_APB5DIVR U(0x40) -#define RCC_RTCDIVR U(0x44) -#define RCC_MSSCKSELR U(0x48) -#define RCC_PLL1CR U(0x80) -#define RCC_PLL1CFGR1 U(0x84) -#define RCC_PLL1CFGR2 U(0x88) -#define RCC_PLL1FRACR U(0x8C) -#define RCC_PLL1CSGR U(0x90) -#define RCC_PLL2CR U(0x94) -#define RCC_PLL2CFGR1 U(0x98) -#define RCC_PLL2CFGR2 U(0x9C) -#define RCC_PLL2FRACR U(0xA0) -#define RCC_PLL2CSGR U(0xA4) -#define RCC_I2C46CKSELR U(0xC0) -#define RCC_SPI6CKSELR U(0xC4) -#define RCC_UART1CKSELR U(0xC8) -#define RCC_RNG1CKSELR U(0xCC) -#define RCC_CPERCKSELR U(0xD0) -#define RCC_STGENCKSELR U(0xD4) -#define RCC_DDRITFCR U(0xD8) -#define RCC_MP_BOOTCR U(0x100) -#define RCC_MP_SREQSETR U(0x104) -#define RCC_MP_SREQCLRR U(0x108) -#define RCC_MP_GCR U(0x10C) -#define RCC_MP_APRSTCR U(0x110) -#define RCC_MP_APRSTSR U(0x114) -#define RCC_BDCR U(0x140) -#define RCC_RDLSICR U(0x144) -#define RCC_APB4RSTSETR U(0x180) -#define RCC_APB4RSTCLRR U(0x184) -#define RCC_APB5RSTSETR U(0x188) -#define RCC_APB5RSTCLRR U(0x18C) -#define RCC_AHB5RSTSETR U(0x190) -#define RCC_AHB5RSTCLRR U(0x194) -#define RCC_AHB6RSTSETR U(0x198) -#define RCC_AHB6RSTCLRR U(0x19C) -#define RCC_TZAHB6RSTSETR U(0x1A0) -#define RCC_TZAHB6RSTCLRR U(0x1A4) -#define RCC_MP_APB4ENSETR U(0x200) -#define RCC_MP_APB4ENCLRR U(0x204) -#define RCC_MP_APB5ENSETR U(0x208) -#define RCC_MP_APB5ENCLRR U(0x20C) -#define RCC_MP_AHB5ENSETR U(0x210) -#define RCC_MP_AHB5ENCLRR U(0x214) -#define RCC_MP_AHB6ENSETR U(0x218) -#define RCC_MP_AHB6ENCLRR U(0x21C) -#define RCC_MP_TZAHB6ENSETR U(0x220) -#define RCC_MP_TZAHB6ENCLRR U(0x224) -#define RCC_MC_APB4ENSETR U(0x280) -#define RCC_MC_APB4ENCLRR U(0x284) -#define RCC_MC_APB5ENSETR U(0x288) -#define RCC_MC_APB5ENCLRR U(0x28C) -#define RCC_MC_AHB5ENSETR U(0x290) -#define RCC_MC_AHB5ENCLRR U(0x294) -#define RCC_MC_AHB6ENSETR U(0x298) -#define RCC_MC_AHB6ENCLRR U(0x29C) -#define RCC_MP_APB4LPENSETR U(0x300) -#define RCC_MP_APB4LPENCLRR U(0x304) -#define RCC_MP_APB5LPENSETR U(0x308) -#define RCC_MP_APB5LPENCLRR U(0x30C) -#define RCC_MP_AHB5LPENSETR U(0x310) -#define RCC_MP_AHB5LPENCLRR U(0x314) -#define RCC_MP_AHB6LPENSETR U(0x318) -#define RCC_MP_AHB6LPENCLRR U(0x31C) -#define RCC_MP_TZAHB6LPENSETR U(0x320) -#define RCC_MP_TZAHB6LPENCLRR U(0x324) -#define RCC_MC_APB4LPENSETR U(0x380) -#define RCC_MC_APB4LPENCLRR U(0x384) -#define RCC_MC_APB5LPENSETR U(0x388) -#define RCC_MC_APB5LPENCLRR U(0x38C) -#define RCC_MC_AHB5LPENSETR U(0x390) -#define RCC_MC_AHB5LPENCLRR U(0x394) -#define RCC_MC_AHB6LPENSETR U(0x398) -#define RCC_MC_AHB6LPENCLRR U(0x39C) -#define RCC_BR_RSTSCLRR U(0x400) -#define RCC_MP_GRSTCSETR U(0x404) -#define RCC_MP_RSTSCLRR U(0x408) -#define RCC_MP_IWDGFZSETR U(0x40C) -#define RCC_MP_IWDGFZCLRR U(0x410) -#define RCC_MP_CIER U(0x414) -#define RCC_MP_CIFR U(0x418) -#define RCC_PWRLPDLYCR U(0x41C) -#define RCC_MP_RSTSSETR U(0x420) -#define RCC_MCO1CFGR U(0x800) -#define RCC_MCO2CFGR U(0x804) -#define RCC_OCRDYR U(0x808) -#define RCC_DBGCFGR U(0x80C) -#define RCC_RCK3SELR U(0x820) -#define RCC_RCK4SELR U(0x824) -#define RCC_TIMG1PRER U(0x828) -#define RCC_TIMG2PRER U(0x82C) -#define RCC_MCUDIVR U(0x830) -#define RCC_APB1DIVR U(0x834) -#define RCC_APB2DIVR U(0x838) -#define RCC_APB3DIVR U(0x83C) -#define RCC_PLL3CR U(0x880) -#define RCC_PLL3CFGR1 U(0x884) -#define RCC_PLL3CFGR2 U(0x888) -#define RCC_PLL3FRACR U(0x88C) -#define RCC_PLL3CSGR U(0x890) -#define RCC_PLL4CR U(0x894) -#define RCC_PLL4CFGR1 U(0x898) -#define RCC_PLL4CFGR2 U(0x89C) -#define RCC_PLL4FRACR U(0x8A0) -#define RCC_PLL4CSGR U(0x8A4) -#define RCC_I2C12CKSELR U(0x8C0) -#define RCC_I2C35CKSELR U(0x8C4) -#define RCC_SAI1CKSELR U(0x8C8) -#define RCC_SAI2CKSELR U(0x8CC) -#define RCC_SAI3CKSELR U(0x8D0) -#define RCC_SAI4CKSELR U(0x8D4) -#define RCC_SPI2S1CKSELR U(0x8D8) -#define RCC_SPI2S23CKSELR U(0x8DC) -#define RCC_SPI45CKSELR U(0x8E0) -#define RCC_UART6CKSELR U(0x8E4) -#define RCC_UART24CKSELR U(0x8E8) -#define RCC_UART35CKSELR U(0x8EC) -#define RCC_UART78CKSELR U(0x8F0) -#define RCC_SDMMC12CKSELR U(0x8F4) -#define RCC_SDMMC3CKSELR U(0x8F8) -#define RCC_ETHCKSELR U(0x8FC) -#define RCC_QSPICKSELR U(0x900) -#define RCC_FMCCKSELR U(0x904) -#define RCC_FDCANCKSELR U(0x90C) -#define RCC_SPDIFCKSELR U(0x914) -#define RCC_CECCKSELR U(0x918) -#define RCC_USBCKSELR U(0x91C) -#define RCC_RNG2CKSELR U(0x920) -#define RCC_DSICKSELR U(0x924) -#define RCC_ADCCKSELR U(0x928) -#define RCC_LPTIM45CKSELR U(0x92C) -#define RCC_LPTIM23CKSELR U(0x930) -#define RCC_LPTIM1CKSELR U(0x934) -#define RCC_APB1RSTSETR U(0x980) -#define RCC_APB1RSTCLRR U(0x984) -#define RCC_APB2RSTSETR U(0x988) -#define RCC_APB2RSTCLRR U(0x98C) -#define RCC_APB3RSTSETR U(0x990) -#define RCC_APB3RSTCLRR U(0x994) -#define RCC_AHB2RSTSETR U(0x998) -#define RCC_AHB2RSTCLRR U(0x99C) -#define RCC_AHB3RSTSETR U(0x9A0) -#define RCC_AHB3RSTCLRR U(0x9A4) -#define RCC_AHB4RSTSETR U(0x9A8) -#define RCC_AHB4RSTCLRR U(0x9AC) -#define RCC_MP_APB1ENSETR U(0xA00) -#define RCC_MP_APB1ENCLRR U(0xA04) -#define RCC_MP_APB2ENSETR U(0xA08) -#define RCC_MP_APB2ENCLRR U(0xA0C) -#define RCC_MP_APB3ENSETR U(0xA10) -#define RCC_MP_APB3ENCLRR U(0xA14) -#define RCC_MP_AHB2ENSETR U(0xA18) -#define RCC_MP_AHB2ENCLRR U(0xA1C) -#define RCC_MP_AHB3ENSETR U(0xA20) -#define RCC_MP_AHB3ENCLRR U(0xA24) -#define RCC_MP_AHB4ENSETR U(0xA28) -#define RCC_MP_AHB4ENCLRR U(0xA2C) -#define RCC_MP_MLAHBENSETR U(0xA38) -#define RCC_MP_MLAHBENCLRR U(0xA3C) -#define RCC_MC_APB1ENSETR U(0xA80) -#define RCC_MC_APB1ENCLRR U(0xA84) -#define RCC_MC_APB2ENSETR U(0xA88) -#define RCC_MC_APB2ENCLRR U(0xA8C) -#define RCC_MC_APB3ENSETR U(0xA90) -#define RCC_MC_APB3ENCLRR U(0xA94) -#define RCC_MC_AHB2ENSETR U(0xA98) -#define RCC_MC_AHB2ENCLRR U(0xA9C) -#define RCC_MC_AHB3ENSETR U(0xAA0) -#define RCC_MC_AHB3ENCLRR U(0xAA4) -#define RCC_MC_AHB4ENSETR U(0xAA8) -#define RCC_MC_AHB4ENCLRR U(0xAAC) -#define RCC_MC_AXIMENSETR U(0xAB0) -#define RCC_MC_AXIMENCLRR U(0xAB4) -#define RCC_MC_MLAHBENSETR U(0xAB8) -#define RCC_MC_MLAHBENCLRR U(0xABC) -#define RCC_MP_APB1LPENSETR U(0xB00) -#define RCC_MP_APB1LPENCLRR U(0xB04) -#define RCC_MP_APB2LPENSETR U(0xB08) -#define RCC_MP_APB2LPENCLRR U(0xB0C) -#define RCC_MP_APB3LPENSETR U(0xB10) -#define RCC_MP_APB3LPENCLRR U(0xB14) -#define RCC_MP_AHB2LPENSETR U(0xB18) -#define RCC_MP_AHB2LPENCLRR U(0xB1C) -#define RCC_MP_AHB3LPENSETR U(0xB20) -#define RCC_MP_AHB3LPENCLRR U(0xB24) -#define RCC_MP_AHB4LPENSETR U(0xB28) -#define RCC_MP_AHB4LPENCLRR U(0xB2C) -#define RCC_MP_AXIMLPENSETR U(0xB30) -#define RCC_MP_AXIMLPENCLRR U(0xB34) -#define RCC_MP_MLAHBLPENSETR U(0xB38) -#define RCC_MP_MLAHBLPENCLRR U(0xB3C) -#define RCC_MC_APB1LPENSETR U(0xB80) -#define RCC_MC_APB1LPENCLRR U(0xB84) -#define RCC_MC_APB2LPENSETR U(0xB88) -#define RCC_MC_APB2LPENCLRR U(0xB8C) -#define RCC_MC_APB3LPENSETR U(0xB90) -#define RCC_MC_APB3LPENCLRR U(0xB94) -#define RCC_MC_AHB2LPENSETR U(0xB98) -#define RCC_MC_AHB2LPENCLRR U(0xB9C) -#define RCC_MC_AHB3LPENSETR U(0xBA0) -#define RCC_MC_AHB3LPENCLRR U(0xBA4) -#define RCC_MC_AHB4LPENSETR U(0xBA8) -#define RCC_MC_AHB4LPENCLRR U(0xBAC) -#define RCC_MC_AXIMLPENSETR U(0xBB0) -#define RCC_MC_AXIMLPENCLRR U(0xBB4) -#define RCC_MC_MLAHBLPENSETR U(0xBB8) -#define RCC_MC_MLAHBLPENCLRR U(0xBBC) -#define RCC_MC_RSTSCLRR U(0xC00) -#define RCC_MC_CIER U(0xC14) -#define RCC_MC_CIFR U(0xC18) -#define RCC_VERR U(0xFF4) -#define RCC_IDR U(0xFF8) -#define RCC_SIDR U(0xFFC) - -#define RCC_OFFSET_MASK GENMASK(11, 0) - -/* Values for RCC_TZCR register */ -#define RCC_TZCR_TZEN BIT(0) -#define RCC_TZCR_MCKPROT BIT(1) +#define RCC_TZCR U(0x00) +#define RCC_OCENSETR U(0x0C) +#define RCC_OCENCLRR U(0x10) +#define RCC_HSICFGR U(0x18) +#define RCC_CSICFGR U(0x1C) +#define RCC_MPCKSELR U(0x20) +#define RCC_ASSCKSELR U(0x24) +#define RCC_RCK12SELR U(0x28) +#define RCC_MPCKDIVR U(0x2C) +#define RCC_AXIDIVR U(0x30) +#define RCC_APB4DIVR U(0x3C) +#define RCC_APB5DIVR U(0x40) +#define RCC_RTCDIVR U(0x44) +#define RCC_MSSCKSELR U(0x48) +#define RCC_PLL1CR U(0x80) +#define RCC_PLL1CFGR1 U(0x84) +#define RCC_PLL1CFGR2 U(0x88) +#define RCC_PLL1FRACR U(0x8C) +#define RCC_PLL1CSGR U(0x90) +#define RCC_PLL2CR U(0x94) +#define RCC_PLL2CFGR1 U(0x98) +#define RCC_PLL2CFGR2 U(0x9C) +#define RCC_PLL2FRACR U(0xA0) +#define RCC_PLL2CSGR U(0xA4) +#define RCC_I2C46CKSELR U(0xC0) +#define RCC_SPI6CKSELR U(0xC4) +#define RCC_UART1CKSELR U(0xC8) +#define RCC_RNG1CKSELR U(0xCC) +#define RCC_CPERCKSELR U(0xD0) +#define RCC_STGENCKSELR U(0xD4) +#define RCC_DDRITFCR U(0xD8) +#define RCC_MP_BOOTCR U(0x100) +#define RCC_MP_SREQSETR U(0x104) +#define RCC_MP_SREQCLRR U(0x108) +#define RCC_MP_GCR U(0x10C) +#define RCC_MP_APRSTCR U(0x110) +#define RCC_MP_APRSTSR U(0x114) +#define RCC_BDCR U(0x140) +#define RCC_RDLSICR U(0x144) +#define RCC_APB4RSTSETR U(0x180) +#define RCC_APB4RSTCLRR U(0x184) +#define RCC_APB5RSTSETR U(0x188) +#define RCC_APB5RSTCLRR U(0x18C) +#define RCC_AHB5RSTSETR U(0x190) +#define RCC_AHB5RSTCLRR U(0x194) +#define RCC_AHB6RSTSETR U(0x198) +#define RCC_AHB6RSTCLRR U(0x19C) +#define RCC_TZAHB6RSTSETR U(0x1A0) +#define RCC_TZAHB6RSTCLRR U(0x1A4) +#define RCC_MP_APB4ENSETR U(0x200) +#define RCC_MP_APB4ENCLRR U(0x204) +#define RCC_MP_APB5ENSETR U(0x208) +#define RCC_MP_APB5ENCLRR U(0x20C) +#define RCC_MP_AHB5ENSETR U(0x210) +#define RCC_MP_AHB5ENCLRR U(0x214) +#define RCC_MP_AHB6ENSETR U(0x218) +#define RCC_MP_AHB6ENCLRR U(0x21C) +#define RCC_MP_TZAHB6ENSETR U(0x220) +#define RCC_MP_TZAHB6ENCLRR U(0x224) +#define RCC_MC_APB4ENSETR U(0x280) +#define RCC_MC_APB4ENCLRR U(0x284) +#define RCC_MC_APB5ENSETR U(0x288) +#define RCC_MC_APB5ENCLRR U(0x28C) +#define RCC_MC_AHB5ENSETR U(0x290) +#define RCC_MC_AHB5ENCLRR U(0x294) +#define RCC_MC_AHB6ENSETR U(0x298) +#define RCC_MC_AHB6ENCLRR U(0x29C) +#define RCC_MP_APB4LPENSETR U(0x300) +#define RCC_MP_APB4LPENCLRR U(0x304) +#define RCC_MP_APB5LPENSETR U(0x308) +#define RCC_MP_APB5LPENCLRR U(0x30C) +#define RCC_MP_AHB5LPENSETR U(0x310) +#define RCC_MP_AHB5LPENCLRR U(0x314) +#define RCC_MP_AHB6LPENSETR U(0x318) +#define RCC_MP_AHB6LPENCLRR U(0x31C) +#define RCC_MP_TZAHB6LPENSETR U(0x320) +#define RCC_MP_TZAHB6LPENCLRR U(0x324) +#define RCC_MC_APB4LPENSETR U(0x380) +#define RCC_MC_APB4LPENCLRR U(0x384) +#define RCC_MC_APB5LPENSETR U(0x388) +#define RCC_MC_APB5LPENCLRR U(0x38C) +#define RCC_MC_AHB5LPENSETR U(0x390) +#define RCC_MC_AHB5LPENCLRR U(0x394) +#define RCC_MC_AHB6LPENSETR U(0x398) +#define RCC_MC_AHB6LPENCLRR U(0x39C) +#define RCC_BR_RSTSCLRR U(0x400) +#define RCC_MP_GRSTCSETR U(0x404) +#define RCC_MP_RSTSCLRR U(0x408) +#define RCC_MP_IWDGFZSETR U(0x40C) +#define RCC_MP_IWDGFZCLRR U(0x410) +#define RCC_MP_CIER U(0x414) +#define RCC_MP_CIFR U(0x418) +#define RCC_PWRLPDLYCR U(0x41C) +#define RCC_MP_RSTSSETR U(0x420) +#define RCC_MCO1CFGR U(0x800) +#define RCC_MCO2CFGR U(0x804) +#define RCC_OCRDYR U(0x808) +#define RCC_DBGCFGR U(0x80C) +#define RCC_RCK3SELR U(0x820) +#define RCC_RCK4SELR U(0x824) +#define RCC_TIMG1PRER U(0x828) +#define RCC_TIMG2PRER U(0x82C) +#define RCC_MCUDIVR U(0x830) +#define RCC_APB1DIVR U(0x834) +#define RCC_APB2DIVR U(0x838) +#define RCC_APB3DIVR U(0x83C) +#define RCC_PLL3CR U(0x880) +#define RCC_PLL3CFGR1 U(0x884) +#define RCC_PLL3CFGR2 U(0x888) +#define RCC_PLL3FRACR U(0x88C) +#define RCC_PLL3CSGR U(0x890) +#define RCC_PLL4CR U(0x894) +#define RCC_PLL4CFGR1 U(0x898) +#define RCC_PLL4CFGR2 U(0x89C) +#define RCC_PLL4FRACR U(0x8A0) +#define RCC_PLL4CSGR U(0x8A4) +#define RCC_I2C12CKSELR U(0x8C0) +#define RCC_I2C35CKSELR U(0x8C4) +#define RCC_SAI1CKSELR U(0x8C8) +#define RCC_SAI2CKSELR U(0x8CC) +#define RCC_SAI3CKSELR U(0x8D0) +#define RCC_SAI4CKSELR U(0x8D4) +#define RCC_SPI2S1CKSELR U(0x8D8) +#define RCC_SPI2S23CKSELR U(0x8DC) +#define RCC_SPI45CKSELR U(0x8E0) +#define RCC_UART6CKSELR U(0x8E4) +#define RCC_UART24CKSELR U(0x8E8) +#define RCC_UART35CKSELR U(0x8EC) +#define RCC_UART78CKSELR U(0x8F0) +#define RCC_SDMMC12CKSELR U(0x8F4) +#define RCC_SDMMC3CKSELR U(0x8F8) +#define RCC_ETHCKSELR U(0x8FC) +#define RCC_QSPICKSELR U(0x900) +#define RCC_FMCCKSELR U(0x904) +#define RCC_FDCANCKSELR U(0x90C) +#define RCC_SPDIFCKSELR U(0x914) +#define RCC_CECCKSELR U(0x918) +#define RCC_USBCKSELR U(0x91C) +#define RCC_RNG2CKSELR U(0x920) +#define RCC_DSICKSELR U(0x924) +#define RCC_ADCCKSELR U(0x928) +#define RCC_LPTIM45CKSELR U(0x92C) +#define RCC_LPTIM23CKSELR U(0x930) +#define RCC_LPTIM1CKSELR U(0x934) +#define RCC_APB1RSTSETR U(0x980) +#define RCC_APB1RSTCLRR U(0x984) +#define RCC_APB2RSTSETR U(0x988) +#define RCC_APB2RSTCLRR U(0x98C) +#define RCC_APB3RSTSETR U(0x990) +#define RCC_APB3RSTCLRR U(0x994) +#define RCC_AHB2RSTSETR U(0x998) +#define RCC_AHB2RSTCLRR U(0x99C) +#define RCC_AHB3RSTSETR U(0x9A0) +#define RCC_AHB3RSTCLRR U(0x9A4) +#define RCC_AHB4RSTSETR U(0x9A8) +#define RCC_AHB4RSTCLRR U(0x9AC) +#define RCC_MP_APB1ENSETR U(0xA00) +#define RCC_MP_APB1ENCLRR U(0xA04) +#define RCC_MP_APB2ENSETR U(0xA08) +#define RCC_MP_APB2ENCLRR U(0xA0C) +#define RCC_MP_APB3ENSETR U(0xA10) +#define RCC_MP_APB3ENCLRR U(0xA14) +#define RCC_MP_AHB2ENSETR U(0xA18) +#define RCC_MP_AHB2ENCLRR U(0xA1C) +#define RCC_MP_AHB3ENSETR U(0xA20) +#define RCC_MP_AHB3ENCLRR U(0xA24) +#define RCC_MP_AHB4ENSETR U(0xA28) +#define RCC_MP_AHB4ENCLRR U(0xA2C) +#define RCC_MP_MLAHBENSETR U(0xA38) +#define RCC_MP_MLAHBENCLRR U(0xA3C) +#define RCC_MC_APB1ENSETR U(0xA80) +#define RCC_MC_APB1ENCLRR U(0xA84) +#define RCC_MC_APB2ENSETR U(0xA88) +#define RCC_MC_APB2ENCLRR U(0xA8C) +#define RCC_MC_APB3ENSETR U(0xA90) +#define RCC_MC_APB3ENCLRR U(0xA94) +#define RCC_MC_AHB2ENSETR U(0xA98) +#define RCC_MC_AHB2ENCLRR U(0xA9C) +#define RCC_MC_AHB3ENSETR U(0xAA0) +#define RCC_MC_AHB3ENCLRR U(0xAA4) +#define RCC_MC_AHB4ENSETR U(0xAA8) +#define RCC_MC_AHB4ENCLRR U(0xAAC) +#define RCC_MC_AXIMENSETR U(0xAB0) +#define RCC_MC_AXIMENCLRR U(0xAB4) +#define RCC_MC_MLAHBENSETR U(0xAB8) +#define RCC_MC_MLAHBENCLRR U(0xABC) +#define RCC_MP_APB1LPENSETR U(0xB00) +#define RCC_MP_APB1LPENCLRR U(0xB04) +#define RCC_MP_APB2LPENSETR U(0xB08) +#define RCC_MP_APB2LPENCLRR U(0xB0C) +#define RCC_MP_APB3LPENSETR U(0xB10) +#define RCC_MP_APB3LPENCLRR U(0xB14) +#define RCC_MP_AHB2LPENSETR U(0xB18) +#define RCC_MP_AHB2LPENCLRR U(0xB1C) +#define RCC_MP_AHB3LPENSETR U(0xB20) +#define RCC_MP_AHB3LPENCLRR U(0xB24) +#define RCC_MP_AHB4LPENSETR U(0xB28) +#define RCC_MP_AHB4LPENCLRR U(0xB2C) +#define RCC_MP_AXIMLPENSETR U(0xB30) +#define RCC_MP_AXIMLPENCLRR U(0xB34) +#define RCC_MP_MLAHBLPENSETR U(0xB38) +#define RCC_MP_MLAHBLPENCLRR U(0xB3C) +#define RCC_MC_APB1LPENSETR U(0xB80) +#define RCC_MC_APB1LPENCLRR U(0xB84) +#define RCC_MC_APB2LPENSETR U(0xB88) +#define RCC_MC_APB2LPENCLRR U(0xB8C) +#define RCC_MC_APB3LPENSETR U(0xB90) +#define RCC_MC_APB3LPENCLRR U(0xB94) +#define RCC_MC_AHB2LPENSETR U(0xB98) +#define RCC_MC_AHB2LPENCLRR U(0xB9C) +#define RCC_MC_AHB3LPENSETR U(0xBA0) +#define RCC_MC_AHB3LPENCLRR U(0xBA4) +#define RCC_MC_AHB4LPENSETR U(0xBA8) +#define RCC_MC_AHB4LPENCLRR U(0xBAC) +#define RCC_MC_AXIMLPENSETR U(0xBB0) +#define RCC_MC_AXIMLPENCLRR U(0xBB4) +#define RCC_MC_MLAHBLPENSETR U(0xBB8) +#define RCC_MC_MLAHBLPENCLRR U(0xBBC) +#define RCC_MC_RSTSCLRR U(0xC00) +#define RCC_MC_CIER U(0xC14) +#define RCC_MC_CIFR U(0xC18) +#define RCC_VERR U(0xFF4) +#define RCC_IDR U(0xFF8) +#define RCC_SIDR U(0xFFC) -/* Used for most of RCC_SELR registers */ -#define RCC_SELR_SRC_MASK GENMASK(2, 0) -#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0) -#define RCC_SELR_SRCRDY BIT(31) - -/* Values of RCC_MPCKSELR register */ -#define RCC_MPCKSELR_HSI 0x00000000 -#define RCC_MPCKSELR_HSE 0x00000001 -#define RCC_MPCKSELR_PLL 0x00000002 -#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003 -#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0) -#define RCC_MPCKSELR_MPUSRC_SHIFT 0 - -/* Values of RCC_ASSCKSELR register */ -#define RCC_ASSCKSELR_HSI 0x00000000 -#define RCC_ASSCKSELR_HSE 0x00000001 -#define RCC_ASSCKSELR_PLL 0x00000002 - -/* Values of RCC_MSSCKSELR register */ -#define RCC_MSSCKSELR_HSI 0x00000000 -#define RCC_MSSCKSELR_HSE 0x00000001 -#define RCC_MSSCKSELR_CSI 0x00000002 -#define RCC_MSSCKSELR_PLL 0x00000003 - -/* Values of RCC_CPERCKSELR register */ -#define RCC_CPERCKSELR_HSI 0x00000000 -#define RCC_CPERCKSELR_CSI 0x00000001 -#define RCC_CPERCKSELR_HSE 0x00000002 -#define RCC_CPERCKSELR_PERSRC_MASK GENMASK(1, 0) -#define RCC_CPERCKSELR_PERSRC_SHIFT 0 - -/* Used for most of DIVR register: max div for RTC */ -#define RCC_DIVR_DIV_MASK GENMASK(5, 0) -#define RCC_DIVR_DIVRDY BIT(31) +/* RCC_TZCR register fields */ +#define RCC_TZCR_TZEN BIT(0) +#define RCC_TZCR_MCKPROT BIT(1) -/* Masks for specific DIVR registers */ -#define RCC_APBXDIV_MASK GENMASK(2, 0) -#define RCC_MPUDIV_MASK GENMASK(2, 0) -#define RCC_AXIDIV_MASK GENMASK(2, 0) -#define RCC_MCUDIV_MASK GENMASK(3, 0) +/* RCC_OCENSETR register fields */ +#define RCC_OCENSETR_HSION BIT(0) +#define RCC_OCENSETR_HSIKERON BIT(1) +#define RCC_OCENSETR_CSION BIT(4) +#define RCC_OCENSETR_CSIKERON BIT(5) +#define RCC_OCENSETR_DIGBYP BIT(7) +#define RCC_OCENSETR_HSEON BIT(8) +#define RCC_OCENSETR_HSEKERON BIT(9) +#define RCC_OCENSETR_HSEBYP BIT(10) +#define RCC_OCENSETR_HSECSSON BIT(11) -/* Used for TIMER Prescaler */ -#define RCC_TIMGXPRER_TIMGXPRE BIT(0) +/* RCC_OCENCLRR register fields */ +#define RCC_OCENCLRR_HSION BIT(0) +#define RCC_OCENCLRR_HSIKERON BIT(1) +#define RCC_OCENCLRR_CSION BIT(4) +#define RCC_OCENCLRR_CSIKERON BIT(5) +#define RCC_OCENCLRR_DIGBYP BIT(7) +#define RCC_OCENCLRR_HSEON BIT(8) +#define RCC_OCENCLRR_HSEKERON BIT(9) +#define RCC_OCENCLRR_HSEBYP BIT(10) -/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */ -#define RCC_MP_ENCLRR_OFFSET U(4) +/* RCC_HSICFGR register fields */ +#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0) +#define RCC_HSICFGR_HSIDIV_SHIFT 0 +#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8) +#define RCC_HSICFGR_HSITRIM_SHIFT 8 +#define RCC_HSICFGR_HSICAL_MASK GENMASK(24, 16) +#define RCC_HSICFGR_HSICAL_SHIFT 16 +#define RCC_HSICFGR_HSICAL_TEMP_MASK GENMASK(27, 25) -/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */ -#define RCC_RSTCLRR_OFFSET U(4) - -/* Fields of RCC_BDCR register */ -#define RCC_BDCR_LSEON BIT(0) -#define RCC_BDCR_LSEBYP BIT(1) -#define RCC_BDCR_LSERDY BIT(2) -#define RCC_BDCR_DIGBYP BIT(3) -#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4) -#define RCC_BDCR_LSEDRV_SHIFT 4 -#define RCC_BDCR_LSECSSON BIT(8) -#define RCC_BDCR_RTCCKEN BIT(20) -#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16) -#define RCC_BDCR_RTCSRC_SHIFT 16 -#define RCC_BDCR_VSWRST BIT(31) - -/* Fields of RCC_RDLSICR register */ -#define RCC_RDLSICR_LSION BIT(0) -#define RCC_RDLSICR_LSIRDY BIT(1) +/* RCC_CSICFGR register fields */ +#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8) +#define RCC_CSICFGR_CSITRIM_SHIFT 8 +#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16) +#define RCC_CSICFGR_CSICAL_SHIFT 16 -/* Used for all RCC_PLLCR registers */ -#define RCC_PLLNCR_PLLON BIT(0) -#define RCC_PLLNCR_PLLRDY BIT(1) -#define RCC_PLLNCR_SSCG_CTRL BIT(2) -#define RCC_PLLNCR_DIVPEN BIT(4) -#define RCC_PLLNCR_DIVQEN BIT(5) -#define RCC_PLLNCR_DIVREN BIT(6) -#define RCC_PLLNCR_DIVEN_SHIFT 4 +/* RCC_MPCKSELR register fields */ +#define RCC_MPCKSELR_HSI 0x00000000 +#define RCC_MPCKSELR_HSE 0x00000001 +#define RCC_MPCKSELR_PLL 0x00000002 +#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003 +#define RCC_MPCKSELR_MPUSRC_MASK GENMASK(1, 0) +#define RCC_MPCKSELR_MPUSRC_SHIFT 0 +#define RCC_MPCKSELR_MPUSRCRDY BIT(31) -/* Used for all RCC_PLLCFGR1 registers */ -#define RCC_PLLNCFGR1_DIVM_SHIFT 16 -#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16) -#define RCC_PLLNCFGR1_DIVN_SHIFT 0 -#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0) -/* Only for PLL3 and PLL4 */ -#define RCC_PLLNCFGR1_IFRGE_SHIFT 24 -#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24) +/* RCC_ASSCKSELR register fields */ +#define RCC_ASSCKSELR_HSI 0x00000000 +#define RCC_ASSCKSELR_HSE 0x00000001 +#define RCC_ASSCKSELR_PLL 0x00000002 +#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0) +#define RCC_ASSCKSELR_AXISSRC_SHIFT 0 +#define RCC_ASSCKSELR_AXISSRCRDY BIT(31) -/* Used for all RCC_PLLCFGR2 registers */ -#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0) -#define RCC_PLLNCFGR2_DIVP_SHIFT 0 -#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0) -#define RCC_PLLNCFGR2_DIVQ_SHIFT 8 -#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8) -#define RCC_PLLNCFGR2_DIVR_SHIFT 16 -#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16) +/* RCC_RCK12SELR register fields */ +#define RCC_RCK12SELR_PLL12SRC_MASK GENMASK(1, 0) +#define RCC_RCK12SELR_PLL12SRC_SHIFT 0 +#define RCC_RCK12SELR_PLL12SRCRDY BIT(31) -/* Used for all RCC_PLLFRACR registers */ -#define RCC_PLLNFRACR_FRACV_SHIFT 3 -#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3) -#define RCC_PLLNFRACR_FRACLE BIT(16) +/* RCC_MPCKDIVR register fields */ +#define RCC_MPCKDIVR_MPUDIV_MASK GENMASK(2, 0) +#define RCC_MPCKDIVR_MPUDIV_SHIFT 0 +#define RCC_MPCKDIVR_MPUDIVRDY BIT(31) -/* Used for all RCC_PLLCSGR registers */ -#define RCC_PLLNCSGR_INC_STEP_SHIFT 16 -#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16) -#define RCC_PLLNCSGR_MOD_PER_SHIFT 0 -#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0) -#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15 -#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15) +/* RCC_AXIDIVR register fields */ +#define RCC_AXIDIVR_AXIDIV_MASK GENMASK(2, 0) +#define RCC_AXIDIVR_AXIDIV_SHIFT 0 +#define RCC_AXIDIVR_AXIDIVRDY BIT(31) -/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */ -#define RCC_OCENR_HSION BIT(0) -#define RCC_OCENR_HSIKERON BIT(1) -#define RCC_OCENR_CSION BIT(4) -#define RCC_OCENR_CSIKERON BIT(5) -#define RCC_OCENR_DIGBYP BIT(7) -#define RCC_OCENR_HSEON BIT(8) -#define RCC_OCENR_HSEKERON BIT(9) -#define RCC_OCENR_HSEBYP BIT(10) -#define RCC_OCENR_HSECSSON BIT(11) - -/* Fields of RCC_OCRDYR register */ -#define RCC_OCRDYR_HSIRDY BIT(0) -#define RCC_OCRDYR_HSIDIVRDY BIT(2) -#define RCC_OCRDYR_CSIRDY BIT(4) -#define RCC_OCRDYR_HSERDY BIT(8) - -/* Fields of RCC_DDRITFCR register */ -#define RCC_DDRITFCR_DDRC1EN BIT(0) -#define RCC_DDRITFCR_DDRC1LPEN BIT(1) -#define RCC_DDRITFCR_DDRC2EN BIT(2) -#define RCC_DDRITFCR_DDRC2LPEN BIT(3) -#define RCC_DDRITFCR_DDRPHYCEN BIT(4) -#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5) -#define RCC_DDRITFCR_DDRCAPBEN BIT(6) -#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7) -#define RCC_DDRITFCR_AXIDCGEN BIT(8) -#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9) -#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10) -#define RCC_DDRITFCR_DDRCAPBRST BIT(14) -#define RCC_DDRITFCR_DDRCAXIRST BIT(15) -#define RCC_DDRITFCR_DDRCORERST BIT(16) -#define RCC_DDRITFCR_DPHYAPBRST BIT(17) -#define RCC_DDRITFCR_DPHYRST BIT(18) -#define RCC_DDRITFCR_DPHYCTLRST BIT(19) -#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20) -#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20 -#define RCC_DDRITFCR_DDRCKMOD_SSR 0 -#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20) -#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21) -#define RCC_DDRITFCR_GSKPCTRL BIT(24) - -/* Fields of RCC_HSICFGR register */ -#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0) -#define RCC_HSICFGR_HSITRIM_SHIFT 8 -#define RCC_HSICFGR_HSITRIM_MASK GENMASK(14, 8) -#define RCC_HSICFGR_HSICAL_SHIFT 16 -#define RCC_HSICFGR_HSICAL_MASK GENMASK(27, 16) - -/* Fields of RCC_CSICFGR register */ -#define RCC_CSICFGR_CSITRIM_SHIFT 8 -#define RCC_CSICFGR_CSITRIM_MASK GENMASK(12, 8) -#define RCC_CSICFGR_CSICAL_SHIFT 16 -#define RCC_CSICFGR_CSICAL_MASK GENMASK(23, 16) +/* RCC_APB4DIVR register fields */ +#define RCC_APB4DIVR_APB4DIV_MASK GENMASK(2, 0) +#define RCC_APB4DIVR_APB4DIV_SHIFT 0 +#define RCC_APB4DIVR_APB4DIVRDY BIT(31) -/* Used for RCC_MCO related operations */ -#define RCC_MCOCFG_MCOON BIT(12) -#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4) -#define RCC_MCOCFG_MCODIV_SHIFT 4 -#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0) - -/* Fields of RCC_DBGCFGR register */ -#define RCC_DBGCFGR_DBGCKEN BIT(8) - -/* RCC register fields for reset reasons */ -#define RCC_MP_RSTSCLRR_PORRSTF BIT(0) -#define RCC_MP_RSTSCLRR_BORRSTF BIT(1) -#define RCC_MP_RSTSCLRR_PADRSTF BIT(2) -#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3) -#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4) -#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6) -#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7) -#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8) -#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9) -#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11) -#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12) -#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13) -#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14) - -/* Global Reset Register */ -#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) -#define RCC_MP_GRSTCSETR_MCURST BIT(1) -#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4) -#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5) - -/* Clock Source Interrupt Flag Register */ -#define RCC_MP_CIFR_MASK U(0x110F1F) -#define RCC_MP_CIFR_LSIRDYF BIT(0) -#define RCC_MP_CIFR_LSERDYF BIT(1) -#define RCC_MP_CIFR_HSIRDYF BIT(2) -#define RCC_MP_CIFR_HSERDYF BIT(3) -#define RCC_MP_CIFR_CSIRDYF BIT(4) -#define RCC_MP_CIFR_PLL1DYF BIT(8) -#define RCC_MP_CIFR_PLL2DYF BIT(9) -#define RCC_MP_CIFR_PLL3DYF BIT(10) -#define RCC_MP_CIFR_PLL4DYF BIT(11) -#define RCC_MP_CIFR_WKUPF BIT(20) - -/* Stop Request Set Register */ -#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0) -#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1) - -/* Stop Request Clear Register */ -#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) -#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) - -/* Values of RCC_UART24CKSELR register */ -#define RCC_UART24CKSELR_HSI 0x00000002 - -/* Values of RCC_MP_APB1ENSETR register */ -#define RCC_MP_APB1ENSETR_UART4EN BIT(16) - -/* Values of RCC_MP_APB5ENSETR register */ -#define RCC_MP_APB5ENSETR_SPI6EN BIT(0) -#define RCC_MP_APB5ENSETR_I2C4EN BIT(2) -#define RCC_MP_APB5ENSETR_I2C6EN BIT(3) -#define RCC_MP_APB5ENSETR_USART1EN BIT(4) -#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8) -#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15) - -/* Values of RCC_MP_AHB4ENSETR register */ -#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6) -#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7) - -/* Values of RCC_MP_AHB5ENSETR register */ -#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0) -#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4) -#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5) -#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6) - -/* Values of RCC_MP_IWDGFZSETR register */ -#define RCC_MP_IWDGFZSETR_IWDG1 BIT(0) -#define RCC_MP_IWDGFZSETR_IWDG2 BIT(1) - -/* Values of RCC_PWRLPDLYCR register */ -#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0) +/* RCC_APB5DIVR register fields */ +#define RCC_APB5DIVR_APB5DIV_MASK GENMASK(2, 0) +#define RCC_APB5DIVR_APB5DIV_SHIFT 0 +#define RCC_APB5DIVR_APB5DIVRDY BIT(31) -/* RCC_ASSCKSELR register fields */ -#define RCC_ASSCKSELR_AXISSRC_MASK GENMASK(2, 0) -#define RCC_ASSCKSELR_AXISSRC_SHIFT 0 +/* RCC_RTCDIVR register fields */ +#define RCC_RTCDIVR_RTCDIV_MASK GENMASK(5, 0) +#define RCC_RTCDIVR_RTCDIV_SHIFT 0 /* RCC_MSSCKSELR register fields */ +#define RCC_MSSCKSELR_HSI 0x00000000 +#define RCC_MSSCKSELR_HSE 0x00000001 +#define RCC_MSSCKSELR_CSI 0x00000002 +#define RCC_MSSCKSELR_PLL 0x00000003 #define RCC_MSSCKSELR_MCUSSRC_MASK GENMASK(1, 0) #define RCC_MSSCKSELR_MCUSSRC_SHIFT 0 +#define RCC_MSSCKSELR_MCUSSRCRDY BIT(31) + +/* RCC_PLL1CR register fields */ +#define RCC_PLL1CR_PLLON BIT(0) +#define RCC_PLL1CR_PLL1RDY BIT(1) +#define RCC_PLL1CR_SSCG_CTRL BIT(2) +#define RCC_PLL1CR_DIVPEN BIT(4) +#define RCC_PLL1CR_DIVQEN BIT(5) +#define RCC_PLL1CR_DIVREN BIT(6) + +/* RCC_PLL1CFGR1 register fields */ +#define RCC_PLL1CFGR1_DIVN_MASK GENMASK(8, 0) +#define RCC_PLL1CFGR1_DIVN_SHIFT 0 +#define RCC_PLL1CFGR1_DIVM1_MASK GENMASK(21, 16) +#define RCC_PLL1CFGR1_DIVM1_SHIFT 16 + +/* RCC_PLL1CFGR2 register fields */ +#define RCC_PLL1CFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLL1CFGR2_DIVP_SHIFT 0 +#define RCC_PLL1CFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLL1CFGR2_DIVQ_SHIFT 8 +#define RCC_PLL1CFGR2_DIVR_MASK GENMASK(22, 16) +#define RCC_PLL1CFGR2_DIVR_SHIFT 16 + +/* RCC_PLL1FRACR register fields */ +#define RCC_PLL1FRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLL1FRACR_FRACV_SHIFT 3 +#define RCC_PLL1FRACR_FRACLE BIT(16) + +/* RCC_PLL1CSGR register fields */ +#define RCC_PLL1CSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLL1CSGR_MOD_PER_SHIFT 0 +#define RCC_PLL1CSGR_TPDFN_DIS BIT(13) +#define RCC_PLL1CSGR_RPDFN_DIS BIT(14) +#define RCC_PLL1CSGR_SSCG_MODE BIT(15) +#define RCC_PLL1CSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLL1CSGR_INC_STEP_SHIFT 16 + +/* RCC_PLL2CR register fields */ +#define RCC_PLL2CR_PLLON BIT(0) +#define RCC_PLL2CR_PLL2RDY BIT(1) +#define RCC_PLL2CR_SSCG_CTRL BIT(2) +#define RCC_PLL2CR_DIVPEN BIT(4) +#define RCC_PLL2CR_DIVQEN BIT(5) +#define RCC_PLL2CR_DIVREN BIT(6) + +/* RCC_PLL2CFGR1 register fields */ +#define RCC_PLL2CFGR1_DIVN_MASK GENMASK(8, 0) +#define RCC_PLL2CFGR1_DIVN_SHIFT 0 +#define RCC_PLL2CFGR1_DIVM2_MASK GENMASK(21, 16) +#define RCC_PLL2CFGR1_DIVM2_SHIFT 16 + +/* RCC_PLL2CFGR2 register fields */ +#define RCC_PLL2CFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLL2CFGR2_DIVP_SHIFT 0 +#define RCC_PLL2CFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLL2CFGR2_DIVQ_SHIFT 8 +#define RCC_PLL2CFGR2_DIVR_MASK GENMASK(22, 16) +#define RCC_PLL2CFGR2_DIVR_SHIFT 16 + +/* RCC_PLL2FRACR register fields */ +#define RCC_PLL2FRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLL2FRACR_FRACV_SHIFT 3 +#define RCC_PLL2FRACR_FRACLE BIT(16) + +/* RCC_PLL2CSGR register fields */ +#define RCC_PLL2CSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLL2CSGR_MOD_PER_SHIFT 0 +#define RCC_PLL2CSGR_TPDFN_DIS BIT(13) +#define RCC_PLL2CSGR_RPDFN_DIS BIT(14) +#define RCC_PLL2CSGR_SSCG_MODE BIT(15) +#define RCC_PLL2CSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLL2CSGR_INC_STEP_SHIFT 16 /* RCC_I2C46CKSELR register fields */ #define RCC_I2C46CKSELR_I2C46SRC_MASK GENMASK(2, 0) @@ -508,10 +417,751 @@ #define RCC_RNG1CKSELR_RNG1SRC_MASK GENMASK(1, 0) #define RCC_RNG1CKSELR_RNG1SRC_SHIFT 0 +/* RCC_CPERCKSELR register fields */ +#define RCC_CPERCKSELR_HSI 0x00000000 +#define RCC_CPERCKSELR_CSI 0x00000001 +#define RCC_CPERCKSELR_HSE 0x00000002 +#define RCC_CPERCKSELR_CKPERSRC_MASK GENMASK(1, 0) +#define RCC_CPERCKSELR_CKPERSRC_SHIFT 0 + /* RCC_STGENCKSELR register fields */ #define RCC_STGENCKSELR_STGENSRC_MASK GENMASK(1, 0) #define RCC_STGENCKSELR_STGENSRC_SHIFT 0 +/* RCC_DDRITFCR register fields */ +#define RCC_DDRITFCR_DDRC1EN BIT(0) +#define RCC_DDRITFCR_DDRC1LPEN BIT(1) +#define RCC_DDRITFCR_DDRC2EN BIT(2) +#define RCC_DDRITFCR_DDRC2LPEN BIT(3) +#define RCC_DDRITFCR_DDRPHYCEN BIT(4) +#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5) +#define RCC_DDRITFCR_DDRCAPBEN BIT(6) +#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7) +#define RCC_DDRITFCR_AXIDCGEN BIT(8) +#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9) +#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10) +#define RCC_DDRITFCR_KERDCG_DLY_MASK GENMASK(13, 11) +#define RCC_DDRITFCR_KERDCG_DLY_SHIFT 11 +#define RCC_DDRITFCR_DDRCAPBRST BIT(14) +#define RCC_DDRITFCR_DDRCAXIRST BIT(15) +#define RCC_DDRITFCR_DDRCORERST BIT(16) +#define RCC_DDRITFCR_DPHYAPBRST BIT(17) +#define RCC_DDRITFCR_DPHYRST BIT(18) +#define RCC_DDRITFCR_DPHYCTLRST BIT(19) +#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20) +#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20 +#define RCC_DDRITFCR_DDRCKMOD_SSR 0 +#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20) +#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21) +#define RCC_DDRITFCR_GSKPMOD BIT(23) +#define RCC_DDRITFCR_GSKPCTRL BIT(24) +#define RCC_DDRITFCR_DFILP_WIDTH_MASK GENMASK(27, 25) +#define RCC_DDRITFCR_DFILP_WIDTH_SHIFT 25 +#define RCC_DDRITFCR_GSKP_DUR_MASK GENMASK(31, 28) +#define RCC_DDRITFCR_GSKP_DUR_SHIFT 28 + +/* RCC_MP_BOOTCR register fields */ +#define RCC_MP_BOOTCR_MCU_BEN BIT(0) +#define RCC_MP_BOOTCR_MPU_BEN BIT(1) + +/* RCC_MP_SREQSETR register fields */ +#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0) +#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1) + +/* RCC_MP_SREQCLRR register fields */ +#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0) +#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1) + +/* RCC_MP_GCR register fields */ +#define RCC_MP_GCR_BOOT_MCU BIT(0) + +/* RCC_MP_APRSTCR register fields */ +#define RCC_MP_APRSTCR_RDCTLEN BIT(0) +#define RCC_MP_APRSTCR_RSTTO_MASK GENMASK(14, 8) +#define RCC_MP_APRSTCR_RSTTO_SHIFT 8 + +/* RCC_MP_APRSTSR register fields */ +#define RCC_MP_APRSTSR_RSTTOV_MASK GENMASK(14, 8) +#define RCC_MP_APRSTSR_RSTTOV_SHIFT 8 + +/* RCC_BDCR register fields */ +#define RCC_BDCR_LSEON BIT(0) +#define RCC_BDCR_LSEBYP BIT(1) +#define RCC_BDCR_LSERDY BIT(2) +#define RCC_BDCR_DIGBYP BIT(3) +#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4) +#define RCC_BDCR_LSEDRV_SHIFT 4 +#define RCC_BDCR_LSECSSON BIT(8) +#define RCC_BDCR_LSECSSD BIT(9) +#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16) +#define RCC_BDCR_RTCSRC_SHIFT 16 +#define RCC_BDCR_RTCCKEN BIT(20) +#define RCC_BDCR_VSWRST BIT(31) + +/* RCC_RDLSICR register fields */ +#define RCC_RDLSICR_LSION BIT(0) +#define RCC_RDLSICR_LSIRDY BIT(1) +#define RCC_RDLSICR_MRD_MASK GENMASK(20, 16) +#define RCC_RDLSICR_MRD_SHIFT 16 +#define RCC_RDLSICR_EADLY_MASK GENMASK(26, 24) +#define RCC_RDLSICR_EADLY_SHIFT 24 +#define RCC_RDLSICR_SPARE_MASK GENMASK(31, 27) +#define RCC_RDLSICR_SPARE_SHIFT 27 + +/* RCC_APB4RSTSETR register fields */ +#define RCC_APB4RSTSETR_LTDCRST BIT(0) +#define RCC_APB4RSTSETR_DSIRST BIT(4) +#define RCC_APB4RSTSETR_DDRPERFMRST BIT(8) +#define RCC_APB4RSTSETR_USBPHYRST BIT(16) + +/* RCC_APB4RSTCLRR register fields */ +#define RCC_APB4RSTCLRR_LTDCRST BIT(0) +#define RCC_APB4RSTCLRR_DSIRST BIT(4) +#define RCC_APB4RSTCLRR_DDRPERFMRST BIT(8) +#define RCC_APB4RSTCLRR_USBPHYRST BIT(16) + +/* RCC_APB5RSTSETR register fields */ +#define RCC_APB5RSTSETR_SPI6RST BIT(0) +#define RCC_APB5RSTSETR_I2C4RST BIT(2) +#define RCC_APB5RSTSETR_I2C6RST BIT(3) +#define RCC_APB5RSTSETR_USART1RST BIT(4) +#define RCC_APB5RSTSETR_STGENRST BIT(20) + +/* RCC_APB5RSTCLRR register fields */ +#define RCC_APB5RSTCLRR_SPI6RST BIT(0) +#define RCC_APB5RSTCLRR_I2C4RST BIT(2) +#define RCC_APB5RSTCLRR_I2C6RST BIT(3) +#define RCC_APB5RSTCLRR_USART1RST BIT(4) +#define RCC_APB5RSTCLRR_STGENRST BIT(20) + +/* RCC_AHB5RSTSETR register fields */ +#define RCC_AHB5RSTSETR_GPIOZRST BIT(0) +#define RCC_AHB5RSTSETR_CRYP1RST BIT(4) +#define RCC_AHB5RSTSETR_HASH1RST BIT(5) +#define RCC_AHB5RSTSETR_RNG1RST BIT(6) +#define RCC_AHB5RSTSETR_AXIMCRST BIT(16) + +/* RCC_AHB5RSTCLRR register fields */ +#define RCC_AHB5RSTCLRR_GPIOZRST BIT(0) +#define RCC_AHB5RSTCLRR_CRYP1RST BIT(4) +#define RCC_AHB5RSTCLRR_HASH1RST BIT(5) +#define RCC_AHB5RSTCLRR_RNG1RST BIT(6) +#define RCC_AHB5RSTCLRR_AXIMCRST BIT(16) + +/* RCC_AHB6RSTSETR register fields */ +#define RCC_AHB6RSTSETR_GPURST BIT(5) +#define RCC_AHB6RSTSETR_ETHMACRST BIT(10) +#define RCC_AHB6RSTSETR_FMCRST BIT(12) +#define RCC_AHB6RSTSETR_QSPIRST BIT(14) +#define RCC_AHB6RSTSETR_SDMMC1RST BIT(16) +#define RCC_AHB6RSTSETR_SDMMC2RST BIT(17) +#define RCC_AHB6RSTSETR_CRC1RST BIT(20) +#define RCC_AHB6RSTSETR_USBHRST BIT(24) + +/* RCC_AHB6RSTCLRR register fields */ +#define RCC_AHB6RSTCLRR_ETHMACRST BIT(10) +#define RCC_AHB6RSTCLRR_FMCRST BIT(12) +#define RCC_AHB6RSTCLRR_QSPIRST BIT(14) +#define RCC_AHB6RSTCLRR_SDMMC1RST BIT(16) +#define RCC_AHB6RSTCLRR_SDMMC2RST BIT(17) +#define RCC_AHB6RSTCLRR_CRC1RST BIT(20) +#define RCC_AHB6RSTCLRR_USBHRST BIT(24) + +/* RCC_TZAHB6RSTSETR register fields */ +#define RCC_TZAHB6RSTSETR_MDMARST BIT(0) + +/* RCC_TZAHB6RSTCLRR register fields */ +#define RCC_TZAHB6RSTCLRR_MDMARST BIT(0) + +/* RCC_MP_APB4ENSETR register fields */ +#define RCC_MP_APB4ENSETR_LTDCEN BIT(0) +#define RCC_MP_APB4ENSETR_DSIEN BIT(4) +#define RCC_MP_APB4ENSETR_DDRPERFMEN BIT(8) +#define RCC_MP_APB4ENSETR_IWDG2APBEN BIT(15) +#define RCC_MP_APB4ENSETR_USBPHYEN BIT(16) +#define RCC_MP_APB4ENSETR_STGENROEN BIT(20) + +/* RCC_MP_APB4ENCLRR register fields */ +#define RCC_MP_APB4ENCLRR_LTDCEN BIT(0) +#define RCC_MP_APB4ENCLRR_DSIEN BIT(4) +#define RCC_MP_APB4ENCLRR_DDRPERFMEN BIT(8) +#define RCC_MP_APB4ENCLRR_IWDG2APBEN BIT(15) +#define RCC_MP_APB4ENCLRR_USBPHYEN BIT(16) +#define RCC_MP_APB4ENCLRR_STGENROEN BIT(20) + +/* RCC_MP_APB5ENSETR register fields */ +#define RCC_MP_APB5ENSETR_SPI6EN BIT(0) +#define RCC_MP_APB5ENSETR_I2C4EN BIT(2) +#define RCC_MP_APB5ENSETR_I2C6EN BIT(3) +#define RCC_MP_APB5ENSETR_USART1EN BIT(4) +#define RCC_MP_APB5ENSETR_RTCAPBEN BIT(8) +#define RCC_MP_APB5ENSETR_TZC1EN BIT(11) +#define RCC_MP_APB5ENSETR_TZC2EN BIT(12) +#define RCC_MP_APB5ENSETR_TZPCEN BIT(13) +#define RCC_MP_APB5ENSETR_IWDG1APBEN BIT(15) +#define RCC_MP_APB5ENSETR_BSECEN BIT(16) +#define RCC_MP_APB5ENSETR_STGENEN BIT(20) + +/* RCC_MP_APB5ENCLRR register fields */ +#define RCC_MP_APB5ENCLRR_SPI6EN BIT(0) +#define RCC_MP_APB5ENCLRR_I2C4EN BIT(2) +#define RCC_MP_APB5ENCLRR_I2C6EN BIT(3) +#define RCC_MP_APB5ENCLRR_USART1EN BIT(4) +#define RCC_MP_APB5ENCLRR_RTCAPBEN BIT(8) +#define RCC_MP_APB5ENCLRR_TZC1EN BIT(11) +#define RCC_MP_APB5ENCLRR_TZC2EN BIT(12) +#define RCC_MP_APB5ENCLRR_TZPCEN BIT(13) +#define RCC_MP_APB5ENCLRR_IWDG1APBEN BIT(15) +#define RCC_MP_APB5ENCLRR_BSECEN BIT(16) +#define RCC_MP_APB5ENCLRR_STGENEN BIT(20) + +/* RCC_MP_AHB5ENSETR register fields */ +#define RCC_MP_AHB5ENSETR_GPIOZEN BIT(0) +#define RCC_MP_AHB5ENSETR_CRYP1EN BIT(4) +#define RCC_MP_AHB5ENSETR_HASH1EN BIT(5) +#define RCC_MP_AHB5ENSETR_RNG1EN BIT(6) +#define RCC_MP_AHB5ENSETR_BKPSRAMEN BIT(8) +#define RCC_MP_AHB5ENSETR_AXIMCEN BIT(16) + +/* RCC_MP_AHB5ENCLRR register fields */ +#define RCC_MP_AHB5ENCLRR_GPIOZEN BIT(0) +#define RCC_MP_AHB5ENCLRR_CRYP1EN BIT(4) +#define RCC_MP_AHB5ENCLRR_HASH1EN BIT(5) +#define RCC_MP_AHB5ENCLRR_RNG1EN BIT(6) +#define RCC_MP_AHB5ENCLRR_BKPSRAMEN BIT(8) +#define RCC_MP_AHB5ENCLRR_AXIMCEN BIT(16) + +/* RCC_MP_AHB6ENSETR register fields */ +#define RCC_MP_AHB6ENSETR_MDMAEN BIT(0) +#define RCC_MP_AHB6ENSETR_GPUEN BIT(5) +#define RCC_MP_AHB6ENSETR_ETHCKEN BIT(7) +#define RCC_MP_AHB6ENSETR_ETHTXEN BIT(8) +#define RCC_MP_AHB6ENSETR_ETHRXEN BIT(9) +#define RCC_MP_AHB6ENSETR_ETHMACEN BIT(10) +#define RCC_MP_AHB6ENSETR_FMCEN BIT(12) +#define RCC_MP_AHB6ENSETR_QSPIEN BIT(14) +#define RCC_MP_AHB6ENSETR_SDMMC1EN BIT(16) +#define RCC_MP_AHB6ENSETR_SDMMC2EN BIT(17) +#define RCC_MP_AHB6ENSETR_CRC1EN BIT(20) +#define RCC_MP_AHB6ENSETR_USBHEN BIT(24) + +/* RCC_MP_AHB6ENCLRR register fields */ +#define RCC_MP_AHB6ENCLRR_MDMAEN BIT(0) +#define RCC_MP_AHB6ENCLRR_GPUEN BIT(5) +#define RCC_MP_AHB6ENCLRR_ETHCKEN BIT(7) +#define RCC_MP_AHB6ENCLRR_ETHTXEN BIT(8) +#define RCC_MP_AHB6ENCLRR_ETHRXEN BIT(9) +#define RCC_MP_AHB6ENCLRR_ETHMACEN BIT(10) +#define RCC_MP_AHB6ENCLRR_FMCEN BIT(12) +#define RCC_MP_AHB6ENCLRR_QSPIEN BIT(14) +#define RCC_MP_AHB6ENCLRR_SDMMC1EN BIT(16) +#define RCC_MP_AHB6ENCLRR_SDMMC2EN BIT(17) +#define RCC_MP_AHB6ENCLRR_CRC1EN BIT(20) +#define RCC_MP_AHB6ENCLRR_USBHEN BIT(24) + +/* RCC_MP_TZAHB6ENSETR register fields */ +#define RCC_MP_TZAHB6ENSETR_MDMAEN BIT(0) + +/* RCC_MP_TZAHB6ENCLRR register fields */ +#define RCC_MP_TZAHB6ENCLRR_MDMAEN BIT(0) + +/* RCC_MC_APB4ENSETR register fields */ +#define RCC_MC_APB4ENSETR_LTDCEN BIT(0) +#define RCC_MC_APB4ENSETR_DSIEN BIT(4) +#define RCC_MC_APB4ENSETR_DDRPERFMEN BIT(8) +#define RCC_MC_APB4ENSETR_USBPHYEN BIT(16) +#define RCC_MC_APB4ENSETR_STGENROEN BIT(20) + +/* RCC_MC_APB4ENCLRR register fields */ +#define RCC_MC_APB4ENCLRR_LTDCEN BIT(0) +#define RCC_MC_APB4ENCLRR_DSIEN BIT(4) +#define RCC_MC_APB4ENCLRR_DDRPERFMEN BIT(8) +#define RCC_MC_APB4ENCLRR_USBPHYEN BIT(16) +#define RCC_MC_APB4ENCLRR_STGENROEN BIT(20) + +/* RCC_MC_APB5ENSETR register fields */ +#define RCC_MC_APB5ENSETR_SPI6EN BIT(0) +#define RCC_MC_APB5ENSETR_I2C4EN BIT(2) +#define RCC_MC_APB5ENSETR_I2C6EN BIT(3) +#define RCC_MC_APB5ENSETR_USART1EN BIT(4) +#define RCC_MC_APB5ENSETR_RTCAPBEN BIT(8) +#define RCC_MC_APB5ENSETR_TZC1EN BIT(11) +#define RCC_MC_APB5ENSETR_TZC2EN BIT(12) +#define RCC_MC_APB5ENSETR_TZPCEN BIT(13) +#define RCC_MC_APB5ENSETR_BSECEN BIT(16) +#define RCC_MC_APB5ENSETR_STGENEN BIT(20) + +/* RCC_MC_APB5ENCLRR register fields */ +#define RCC_MC_APB5ENCLRR_SPI6EN BIT(0) +#define RCC_MC_APB5ENCLRR_I2C4EN BIT(2) +#define RCC_MC_APB5ENCLRR_I2C6EN BIT(3) +#define RCC_MC_APB5ENCLRR_USART1EN BIT(4) +#define RCC_MC_APB5ENCLRR_RTCAPBEN BIT(8) +#define RCC_MC_APB5ENCLRR_TZC1EN BIT(11) +#define RCC_MC_APB5ENCLRR_TZC2EN BIT(12) +#define RCC_MC_APB5ENCLRR_TZPCEN BIT(13) +#define RCC_MC_APB5ENCLRR_BSECEN BIT(16) +#define RCC_MC_APB5ENCLRR_STGENEN BIT(20) + +/* RCC_MC_AHB5ENSETR register fields */ +#define RCC_MC_AHB5ENSETR_GPIOZEN BIT(0) +#define RCC_MC_AHB5ENSETR_CRYP1EN BIT(4) +#define RCC_MC_AHB5ENSETR_HASH1EN BIT(5) +#define RCC_MC_AHB5ENSETR_RNG1EN BIT(6) +#define RCC_MC_AHB5ENSETR_BKPSRAMEN BIT(8) + +/* RCC_MC_AHB5ENCLRR register fields */ +#define RCC_MC_AHB5ENCLRR_GPIOZEN BIT(0) +#define RCC_MC_AHB5ENCLRR_CRYP1EN BIT(4) +#define RCC_MC_AHB5ENCLRR_HASH1EN BIT(5) +#define RCC_MC_AHB5ENCLRR_RNG1EN BIT(6) +#define RCC_MC_AHB5ENCLRR_BKPSRAMEN BIT(8) + +/* RCC_MC_AHB6ENSETR register fields */ +#define RCC_MC_AHB6ENSETR_MDMAEN BIT(0) +#define RCC_MC_AHB6ENSETR_GPUEN BIT(5) +#define RCC_MC_AHB6ENSETR_ETHCKEN BIT(7) +#define RCC_MC_AHB6ENSETR_ETHTXEN BIT(8) +#define RCC_MC_AHB6ENSETR_ETHRXEN BIT(9) +#define RCC_MC_AHB6ENSETR_ETHMACEN BIT(10) +#define RCC_MC_AHB6ENSETR_FMCEN BIT(12) +#define RCC_MC_AHB6ENSETR_QSPIEN BIT(14) +#define RCC_MC_AHB6ENSETR_SDMMC1EN BIT(16) +#define RCC_MC_AHB6ENSETR_SDMMC2EN BIT(17) +#define RCC_MC_AHB6ENSETR_CRC1EN BIT(20) +#define RCC_MC_AHB6ENSETR_USBHEN BIT(24) + +/* RCC_MC_AHB6ENCLRR register fields */ +#define RCC_MC_AHB6ENCLRR_MDMAEN BIT(0) +#define RCC_MC_AHB6ENCLRR_GPUEN BIT(5) +#define RCC_MC_AHB6ENCLRR_ETHCKEN BIT(7) +#define RCC_MC_AHB6ENCLRR_ETHTXEN BIT(8) +#define RCC_MC_AHB6ENCLRR_ETHRXEN BIT(9) +#define RCC_MC_AHB6ENCLRR_ETHMACEN BIT(10) +#define RCC_MC_AHB6ENCLRR_FMCEN BIT(12) +#define RCC_MC_AHB6ENCLRR_QSPIEN BIT(14) +#define RCC_MC_AHB6ENCLRR_SDMMC1EN BIT(16) +#define RCC_MC_AHB6ENCLRR_SDMMC2EN BIT(17) +#define RCC_MC_AHB6ENCLRR_CRC1EN BIT(20) +#define RCC_MC_AHB6ENCLRR_USBHEN BIT(24) + +/* RCC_MP_APB4LPENSETR register fields */ +#define RCC_MP_APB4LPENSETR_LTDCLPEN BIT(0) +#define RCC_MP_APB4LPENSETR_DSILPEN BIT(4) +#define RCC_MP_APB4LPENSETR_DDRPERFMLPEN BIT(8) +#define RCC_MP_APB4LPENSETR_IWDG2APBLPEN BIT(15) +#define RCC_MP_APB4LPENSETR_USBPHYLPEN BIT(16) +#define RCC_MP_APB4LPENSETR_STGENROLPEN BIT(20) +#define RCC_MP_APB4LPENSETR_STGENROSTPEN BIT(21) + +/* RCC_MP_APB4LPENCLRR register fields */ +#define RCC_MP_APB4LPENCLRR_LTDCLPEN BIT(0) +#define RCC_MP_APB4LPENCLRR_DSILPEN BIT(4) +#define RCC_MP_APB4LPENCLRR_DDRPERFMLPEN BIT(8) +#define RCC_MP_APB4LPENCLRR_IWDG2APBLPEN BIT(15) +#define RCC_MP_APB4LPENCLRR_USBPHYLPEN BIT(16) +#define RCC_MP_APB4LPENCLRR_STGENROLPEN BIT(20) +#define RCC_MP_APB4LPENCLRR_STGENROSTPEN BIT(21) + +/* RCC_MP_APB5LPENSETR register fields */ +#define RCC_MP_APB5LPENSETR_SPI6LPEN BIT(0) +#define RCC_MP_APB5LPENSETR_I2C4LPEN BIT(2) +#define RCC_MP_APB5LPENSETR_I2C6LPEN BIT(3) +#define RCC_MP_APB5LPENSETR_USART1LPEN BIT(4) +#define RCC_MP_APB5LPENSETR_RTCAPBLPEN BIT(8) +#define RCC_MP_APB5LPENSETR_TZC1LPEN BIT(11) +#define RCC_MP_APB5LPENSETR_TZC2LPEN BIT(12) +#define RCC_MP_APB5LPENSETR_TZPCLPEN BIT(13) +#define RCC_MP_APB5LPENSETR_IWDG1APBLPEN BIT(15) +#define RCC_MP_APB5LPENSETR_BSECLPEN BIT(16) +#define RCC_MP_APB5LPENSETR_STGENLPEN BIT(20) +#define RCC_MP_APB5LPENSETR_STGENSTPEN BIT(21) + +/* RCC_MP_APB5LPENCLRR register fields */ +#define RCC_MP_APB5LPENCLRR_SPI6LPEN BIT(0) +#define RCC_MP_APB5LPENCLRR_I2C4LPEN BIT(2) +#define RCC_MP_APB5LPENCLRR_I2C6LPEN BIT(3) +#define RCC_MP_APB5LPENCLRR_USART1LPEN BIT(4) +#define RCC_MP_APB5LPENCLRR_RTCAPBLPEN BIT(8) +#define RCC_MP_APB5LPENCLRR_TZC1LPEN BIT(11) +#define RCC_MP_APB5LPENCLRR_TZC2LPEN BIT(12) +#define RCC_MP_APB5LPENCLRR_TZPCLPEN BIT(13) +#define RCC_MP_APB5LPENCLRR_IWDG1APBLPEN BIT(15) +#define RCC_MP_APB5LPENCLRR_BSECLPEN BIT(16) +#define RCC_MP_APB5LPENCLRR_STGENLPEN BIT(20) +#define RCC_MP_APB5LPENCLRR_STGENSTPEN BIT(21) + +/* RCC_MP_AHB5LPENSETR register fields */ +#define RCC_MP_AHB5LPENSETR_GPIOZLPEN BIT(0) +#define RCC_MP_AHB5LPENSETR_CRYP1LPEN BIT(4) +#define RCC_MP_AHB5LPENSETR_HASH1LPEN BIT(5) +#define RCC_MP_AHB5LPENSETR_RNG1LPEN BIT(6) +#define RCC_MP_AHB5LPENSETR_BKPSRAMLPEN BIT(8) + +/* RCC_MP_AHB5LPENCLRR register fields */ +#define RCC_MP_AHB5LPENCLRR_GPIOZLPEN BIT(0) +#define RCC_MP_AHB5LPENCLRR_CRYP1LPEN BIT(4) +#define RCC_MP_AHB5LPENCLRR_HASH1LPEN BIT(5) +#define RCC_MP_AHB5LPENCLRR_RNG1LPEN BIT(6) +#define RCC_MP_AHB5LPENCLRR_BKPSRAMLPEN BIT(8) + +/* RCC_MP_AHB6LPENSETR register fields */ +#define RCC_MP_AHB6LPENSETR_MDMALPEN BIT(0) +#define RCC_MP_AHB6LPENSETR_GPULPEN BIT(5) +#define RCC_MP_AHB6LPENSETR_ETHCKLPEN BIT(7) +#define RCC_MP_AHB6LPENSETR_ETHTXLPEN BIT(8) +#define RCC_MP_AHB6LPENSETR_ETHRXLPEN BIT(9) +#define RCC_MP_AHB6LPENSETR_ETHMACLPEN BIT(10) +#define RCC_MP_AHB6LPENSETR_ETHSTPEN BIT(11) +#define RCC_MP_AHB6LPENSETR_FMCLPEN BIT(12) +#define RCC_MP_AHB6LPENSETR_QSPILPEN BIT(14) +#define RCC_MP_AHB6LPENSETR_SDMMC1LPEN BIT(16) +#define RCC_MP_AHB6LPENSETR_SDMMC2LPEN BIT(17) +#define RCC_MP_AHB6LPENSETR_CRC1LPEN BIT(20) +#define RCC_MP_AHB6LPENSETR_USBHLPEN BIT(24) + +/* RCC_MP_AHB6LPENCLRR register fields */ +#define RCC_MP_AHB6LPENCLRR_MDMALPEN BIT(0) +#define RCC_MP_AHB6LPENCLRR_GPULPEN BIT(5) +#define RCC_MP_AHB6LPENCLRR_ETHCKLPEN BIT(7) +#define RCC_MP_AHB6LPENCLRR_ETHTXLPEN BIT(8) +#define RCC_MP_AHB6LPENCLRR_ETHRXLPEN BIT(9) +#define RCC_MP_AHB6LPENCLRR_ETHMACLPEN BIT(10) +#define RCC_MP_AHB6LPENCLRR_ETHSTPEN BIT(11) +#define RCC_MP_AHB6LPENCLRR_FMCLPEN BIT(12) +#define RCC_MP_AHB6LPENCLRR_QSPILPEN BIT(14) +#define RCC_MP_AHB6LPENCLRR_SDMMC1LPEN BIT(16) +#define RCC_MP_AHB6LPENCLRR_SDMMC2LPEN BIT(17) +#define RCC_MP_AHB6LPENCLRR_CRC1LPEN BIT(20) +#define RCC_MP_AHB6LPENCLRR_USBHLPEN BIT(24) + +/* RCC_MP_TZAHB6LPENSETR register fields */ +#define RCC_MP_TZAHB6LPENSETR_MDMALPEN BIT(0) + +/* RCC_MP_TZAHB6LPENCLRR register fields */ +#define RCC_MP_TZAHB6LPENCLRR_MDMALPEN BIT(0) + +/* RCC_MC_APB4LPENSETR register fields */ +#define RCC_MC_APB4LPENSETR_LTDCLPEN BIT(0) +#define RCC_MC_APB4LPENSETR_DSILPEN BIT(4) +#define RCC_MC_APB4LPENSETR_DDRPERFMLPEN BIT(8) +#define RCC_MC_APB4LPENSETR_USBPHYLPEN BIT(16) +#define RCC_MC_APB4LPENSETR_STGENROLPEN BIT(20) +#define RCC_MC_APB4LPENSETR_STGENROSTPEN BIT(21) + +/* RCC_MC_APB4LPENCLRR register fields */ +#define RCC_MC_APB4LPENCLRR_LTDCLPEN BIT(0) +#define RCC_MC_APB4LPENCLRR_DSILPEN BIT(4) +#define RCC_MC_APB4LPENCLRR_DDRPERFMLPEN BIT(8) +#define RCC_MC_APB4LPENCLRR_USBPHYLPEN BIT(16) +#define RCC_MC_APB4LPENCLRR_STGENROLPEN BIT(20) +#define RCC_MC_APB4LPENCLRR_STGENROSTPEN BIT(21) + +/* RCC_MC_APB5LPENSETR register fields */ +#define RCC_MC_APB5LPENSETR_SPI6LPEN BIT(0) +#define RCC_MC_APB5LPENSETR_I2C4LPEN BIT(2) +#define RCC_MC_APB5LPENSETR_I2C6LPEN BIT(3) +#define RCC_MC_APB5LPENSETR_USART1LPEN BIT(4) +#define RCC_MC_APB5LPENSETR_RTCAPBLPEN BIT(8) +#define RCC_MC_APB5LPENSETR_TZC1LPEN BIT(11) +#define RCC_MC_APB5LPENSETR_TZC2LPEN BIT(12) +#define RCC_MC_APB5LPENSETR_TZPCLPEN BIT(13) +#define RCC_MC_APB5LPENSETR_BSECLPEN BIT(16) +#define RCC_MC_APB5LPENSETR_STGENLPEN BIT(20) +#define RCC_MC_APB5LPENSETR_STGENSTPEN BIT(21) + +/* RCC_MC_APB5LPENCLRR register fields */ +#define RCC_MC_APB5LPENCLRR_SPI6LPEN BIT(0) +#define RCC_MC_APB5LPENCLRR_I2C4LPEN BIT(2) +#define RCC_MC_APB5LPENCLRR_I2C6LPEN BIT(3) +#define RCC_MC_APB5LPENCLRR_USART1LPEN BIT(4) +#define RCC_MC_APB5LPENCLRR_RTCAPBLPEN BIT(8) +#define RCC_MC_APB5LPENCLRR_TZC1LPEN BIT(11) +#define RCC_MC_APB5LPENCLRR_TZC2LPEN BIT(12) +#define RCC_MC_APB5LPENCLRR_TZPCLPEN BIT(13) +#define RCC_MC_APB5LPENCLRR_BSECLPEN BIT(16) +#define RCC_MC_APB5LPENCLRR_STGENLPEN BIT(20) +#define RCC_MC_APB5LPENCLRR_STGENSTPEN BIT(21) + +/* RCC_MC_AHB5LPENSETR register fields */ +#define RCC_MC_AHB5LPENSETR_GPIOZLPEN BIT(0) +#define RCC_MC_AHB5LPENSETR_CRYP1LPEN BIT(4) +#define RCC_MC_AHB5LPENSETR_HASH1LPEN BIT(5) +#define RCC_MC_AHB5LPENSETR_RNG1LPEN BIT(6) +#define RCC_MC_AHB5LPENSETR_BKPSRAMLPEN BIT(8) + +/* RCC_MC_AHB5LPENCLRR register fields */ +#define RCC_MC_AHB5LPENCLRR_GPIOZLPEN BIT(0) +#define RCC_MC_AHB5LPENCLRR_CRYP1LPEN BIT(4) +#define RCC_MC_AHB5LPENCLRR_HASH1LPEN BIT(5) +#define RCC_MC_AHB5LPENCLRR_RNG1LPEN BIT(6) +#define RCC_MC_AHB5LPENCLRR_BKPSRAMLPEN BIT(8) + +/* RCC_MC_AHB6LPENSETR register fields */ +#define RCC_MC_AHB6LPENSETR_MDMALPEN BIT(0) +#define RCC_MC_AHB6LPENSETR_GPULPEN BIT(5) +#define RCC_MC_AHB6LPENSETR_ETHCKLPEN BIT(7) +#define RCC_MC_AHB6LPENSETR_ETHTXLPEN BIT(8) +#define RCC_MC_AHB6LPENSETR_ETHRXLPEN BIT(9) +#define RCC_MC_AHB6LPENSETR_ETHMACLPEN BIT(10) +#define RCC_MC_AHB6LPENSETR_ETHSTPEN BIT(11) +#define RCC_MC_AHB6LPENSETR_FMCLPEN BIT(12) +#define RCC_MC_AHB6LPENSETR_QSPILPEN BIT(14) +#define RCC_MC_AHB6LPENSETR_SDMMC1LPEN BIT(16) +#define RCC_MC_AHB6LPENSETR_SDMMC2LPEN BIT(17) +#define RCC_MC_AHB6LPENSETR_CRC1LPEN BIT(20) +#define RCC_MC_AHB6LPENSETR_USBHLPEN BIT(24) + +/* RCC_MC_AHB6LPENCLRR register fields */ +#define RCC_MC_AHB6LPENCLRR_MDMALPEN BIT(0) +#define RCC_MC_AHB6LPENCLRR_GPULPEN BIT(5) +#define RCC_MC_AHB6LPENCLRR_ETHCKLPEN BIT(7) +#define RCC_MC_AHB6LPENCLRR_ETHTXLPEN BIT(8) +#define RCC_MC_AHB6LPENCLRR_ETHRXLPEN BIT(9) +#define RCC_MC_AHB6LPENCLRR_ETHMACLPEN BIT(10) +#define RCC_MC_AHB6LPENCLRR_ETHSTPEN BIT(11) +#define RCC_MC_AHB6LPENCLRR_FMCLPEN BIT(12) +#define RCC_MC_AHB6LPENCLRR_QSPILPEN BIT(14) +#define RCC_MC_AHB6LPENCLRR_SDMMC1LPEN BIT(16) +#define RCC_MC_AHB6LPENCLRR_SDMMC2LPEN BIT(17) +#define RCC_MC_AHB6LPENCLRR_CRC1LPEN BIT(20) +#define RCC_MC_AHB6LPENCLRR_USBHLPEN BIT(24) + +/* RCC_BR_RSTSCLRR register fields */ +#define RCC_BR_RSTSCLRR_PORRSTF BIT(0) +#define RCC_BR_RSTSCLRR_BORRSTF BIT(1) +#define RCC_BR_RSTSCLRR_PADRSTF BIT(2) +#define RCC_BR_RSTSCLRR_HCSSRSTF BIT(3) +#define RCC_BR_RSTSCLRR_VCORERSTF BIT(4) +#define RCC_BR_RSTSCLRR_MPSYSRSTF BIT(6) +#define RCC_BR_RSTSCLRR_MCSYSRSTF BIT(7) +#define RCC_BR_RSTSCLRR_IWDG1RSTF BIT(8) +#define RCC_BR_RSTSCLRR_IWDG2RSTF BIT(9) +#define RCC_BR_RSTSCLRR_MPUP0RSTF BIT(13) +#define RCC_BR_RSTSCLRR_MPUP1RSTF BIT(14) + +/* RCC_MP_GRSTCSETR register fields */ +#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) +#define RCC_MP_GRSTCSETR_MCURST BIT(1) +#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4) +#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5) + +/* RCC_MP_RSTSCLRR register fields */ +#define RCC_MP_RSTSCLRR_PORRSTF BIT(0) +#define RCC_MP_RSTSCLRR_BORRSTF BIT(1) +#define RCC_MP_RSTSCLRR_PADRSTF BIT(2) +#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3) +#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4) +#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6) +#define RCC_MP_RSTSCLRR_MCSYSRSTF BIT(7) +#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8) +#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9) +#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11) +#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12) +#define RCC_MP_RSTSCLRR_MPUP0RSTF BIT(13) +#define RCC_MP_RSTSCLRR_MPUP1RSTF BIT(14) +#define RCC_MP_RSTSCLRR_SPARE BIT(15) + +/* RCC_MP_IWDGFZSETR register fields */ +#define RCC_MP_IWDGFZSETR_FZ_IWDG1 BIT(0) +#define RCC_MP_IWDGFZSETR_FZ_IWDG2 BIT(1) + +/* RCC_MP_IWDGFZCLRR register fields */ +#define RCC_MP_IWDGFZCLRR_FZ_IWDG1 BIT(0) +#define RCC_MP_IWDGFZCLRR_FZ_IWDG2 BIT(1) + +/* RCC_MP_CIER register fields */ +#define RCC_MP_CIER_LSIRDYIE BIT(0) +#define RCC_MP_CIER_LSERDYIE BIT(1) +#define RCC_MP_CIER_HSIRDYIE BIT(2) +#define RCC_MP_CIER_HSERDYIE BIT(3) +#define RCC_MP_CIER_CSIRDYIE BIT(4) +#define RCC_MP_CIER_PLL1DYIE BIT(8) +#define RCC_MP_CIER_PLL2DYIE BIT(9) +#define RCC_MP_CIER_PLL3DYIE BIT(10) +#define RCC_MP_CIER_PLL4DYIE BIT(11) +#define RCC_MP_CIER_LSECSSIE BIT(16) +#define RCC_MP_CIER_WKUPIE BIT(20) + +/* RCC_MP_CIFR register fields */ +#define RCC_MP_CIFR_MASK U(0x110F1F) +#define RCC_MP_CIFR_LSIRDYF BIT(0) +#define RCC_MP_CIFR_LSERDYF BIT(1) +#define RCC_MP_CIFR_HSIRDYF BIT(2) +#define RCC_MP_CIFR_HSERDYF BIT(3) +#define RCC_MP_CIFR_CSIRDYF BIT(4) +#define RCC_MP_CIFR_PLL1DYF BIT(8) +#define RCC_MP_CIFR_PLL2DYF BIT(9) +#define RCC_MP_CIFR_PLL3DYF BIT(10) +#define RCC_MP_CIFR_PLL4DYF BIT(11) +#define RCC_MP_CIFR_LSECSSF BIT(16) +#define RCC_MP_CIFR_WKUPF BIT(20) + +/* RCC_PWRLPDLYCR register fields */ +#define RCC_PWRLPDLYCR_PWRLP_DLY_MASK GENMASK(21, 0) +#define RCC_PWRLPDLYCR_PWRLP_DLY_SHIFT 0 +#define RCC_PWRLPDLYCR_MCTMPSKP BIT(24) + +/* RCC_MP_RSTSSETR register fields */ +#define RCC_MP_RSTSSETR_PORRSTF BIT(0) +#define RCC_MP_RSTSSETR_BORRSTF BIT(1) +#define RCC_MP_RSTSSETR_PADRSTF BIT(2) +#define RCC_MP_RSTSSETR_HCSSRSTF BIT(3) +#define RCC_MP_RSTSSETR_VCORERSTF BIT(4) +#define RCC_MP_RSTSSETR_MPSYSRSTF BIT(6) +#define RCC_MP_RSTSSETR_MCSYSRSTF BIT(7) +#define RCC_MP_RSTSSETR_IWDG1RSTF BIT(8) +#define RCC_MP_RSTSSETR_IWDG2RSTF BIT(9) +#define RCC_MP_RSTSSETR_STDBYRSTF BIT(11) +#define RCC_MP_RSTSSETR_CSTDBYRSTF BIT(12) +#define RCC_MP_RSTSSETR_MPUP0RSTF BIT(13) +#define RCC_MP_RSTSSETR_MPUP1RSTF BIT(14) +#define RCC_MP_RSTSSETR_SPARE BIT(15) + +/* RCC_MCO1CFGR register fields */ +#define RCC_MCO1CFGR_MCO1SEL_MASK GENMASK(2, 0) +#define RCC_MCO1CFGR_MCO1SEL_SHIFT 0 +#define RCC_MCO1CFGR_MCO1DIV_MASK GENMASK(7, 4) +#define RCC_MCO1CFGR_MCO1DIV_SHIFT 4 +#define RCC_MCO1CFGR_MCO1ON BIT(12) + +/* RCC_MCO2CFGR register fields */ +#define RCC_MCO2CFGR_MCO2SEL_MASK GENMASK(2, 0) +#define RCC_MCO2CFGR_MCO2SEL_SHIFT 0 +#define RCC_MCO2CFGR_MCO2DIV_MASK GENMASK(7, 4) +#define RCC_MCO2CFGR_MCO2DIV_SHIFT 4 +#define RCC_MCO2CFGR_MCO2ON BIT(12) + +/* RCC_OCRDYR register fields */ +#define RCC_OCRDYR_HSIRDY BIT(0) +#define RCC_OCRDYR_HSIDIVRDY BIT(2) +#define RCC_OCRDYR_CSIRDY BIT(4) +#define RCC_OCRDYR_HSERDY BIT(8) +#define RCC_OCRDYR_MPUCKRDY BIT(23) +#define RCC_OCRDYR_AXICKRDY BIT(24) +#define RCC_OCRDYR_CKREST BIT(25) + +/* RCC_DBGCFGR register fields */ +#define RCC_DBGCFGR_TRACEDIV_MASK GENMASK(2, 0) +#define RCC_DBGCFGR_TRACEDIV_SHIFT 0 +#define RCC_DBGCFGR_DBGCKEN BIT(8) +#define RCC_DBGCFGR_TRACECKEN BIT(9) +#define RCC_DBGCFGR_DBGRST BIT(12) + +/* RCC_RCK3SELR register fields */ +#define RCC_RCK3SELR_PLL3SRC_MASK GENMASK(1, 0) +#define RCC_RCK3SELR_PLL3SRC_SHIFT 0 +#define RCC_RCK3SELR_PLL3SRCRDY BIT(31) + +/* RCC_RCK4SELR register fields */ +#define RCC_RCK4SELR_PLL4SRC_MASK GENMASK(1, 0) +#define RCC_RCK4SELR_PLL4SRC_SHIFT 0 +#define RCC_RCK4SELR_PLL4SRCRDY BIT(31) + +/* RCC_TIMG1PRER register fields */ +#define RCC_TIMG1PRER_TIMG1PRE BIT(0) +#define RCC_TIMG1PRER_TIMG1PRERDY BIT(31) + +/* RCC_TIMG2PRER register fields */ +#define RCC_TIMG2PRER_TIMG2PRE BIT(0) +#define RCC_TIMG2PRER_TIMG2PRERDY BIT(31) + +/* RCC_MCUDIVR register fields */ +#define RCC_MCUDIVR_MCUDIV_MASK GENMASK(3, 0) +#define RCC_MCUDIVR_MCUDIV_SHIFT 0 +#define RCC_MCUDIVR_MCUDIVRDY BIT(31) + +/* RCC_APB1DIVR register fields */ +#define RCC_APB1DIVR_APB1DIV_MASK GENMASK(2, 0) +#define RCC_APB1DIVR_APB1DIV_SHIFT 0 +#define RCC_APB1DIVR_APB1DIVRDY BIT(31) + +/* RCC_APB2DIVR register fields */ +#define RCC_APB2DIVR_APB2DIV_MASK GENMASK(2, 0) +#define RCC_APB2DIVR_APB2DIV_SHIFT 0 +#define RCC_APB2DIVR_APB2DIVRDY BIT(31) + +/* RCC_APB3DIVR register fields */ +#define RCC_APB3DIVR_APB3DIV_MASK GENMASK(2, 0) +#define RCC_APB3DIVR_APB3DIV_SHIFT 0 +#define RCC_APB3DIVR_APB3DIVRDY BIT(31) + +/* RCC_PLL3CR register fields */ +#define RCC_PLL3CR_PLLON BIT(0) +#define RCC_PLL3CR_PLL3RDY BIT(1) +#define RCC_PLL3CR_SSCG_CTRL BIT(2) +#define RCC_PLL3CR_DIVPEN BIT(4) +#define RCC_PLL3CR_DIVQEN BIT(5) +#define RCC_PLL3CR_DIVREN BIT(6) + +/* RCC_PLL3CFGR1 register fields */ +#define RCC_PLL3CFGR1_DIVN_MASK GENMASK(8, 0) +#define RCC_PLL3CFGR1_DIVN_SHIFT 0 +#define RCC_PLL3CFGR1_DIVM3_MASK GENMASK(21, 16) +#define RCC_PLL3CFGR1_DIVM3_SHIFT 16 +#define RCC_PLL3CFGR1_IFRGE_MASK GENMASK(25, 24) +#define RCC_PLL3CFGR1_IFRGE_SHIFT 24 + +/* RCC_PLL3CFGR2 register fields */ +#define RCC_PLL3CFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLL3CFGR2_DIVP_SHIFT 0 +#define RCC_PLL3CFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLL3CFGR2_DIVQ_SHIFT 8 +#define RCC_PLL3CFGR2_DIVR_MASK GENMASK(22, 16) +#define RCC_PLL3CFGR2_DIVR_SHIFT 16 + +/* RCC_PLL3FRACR register fields */ +#define RCC_PLL3FRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLL3FRACR_FRACV_SHIFT 3 +#define RCC_PLL3FRACR_FRACLE BIT(16) + +/* RCC_PLL3CSGR register fields */ +#define RCC_PLL3CSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLL3CSGR_MOD_PER_SHIFT 0 +#define RCC_PLL3CSGR_TPDFN_DIS BIT(13) +#define RCC_PLL3CSGR_RPDFN_DIS BIT(14) +#define RCC_PLL3CSGR_SSCG_MODE BIT(15) +#define RCC_PLL3CSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLL3CSGR_INC_STEP_SHIFT 16 + +/* RCC_PLL4CR register fields */ +#define RCC_PLL4CR_PLLON BIT(0) +#define RCC_PLL4CR_PLL4RDY BIT(1) +#define RCC_PLL4CR_SSCG_CTRL BIT(2) +#define RCC_PLL4CR_DIVPEN BIT(4) +#define RCC_PLL4CR_DIVQEN BIT(5) +#define RCC_PLL4CR_DIVREN BIT(6) + +/* RCC_PLL4CFGR1 register fields */ +#define RCC_PLL4CFGR1_DIVN_MASK GENMASK(8, 0) +#define RCC_PLL4CFGR1_DIVN_SHIFT 0 +#define RCC_PLL4CFGR1_DIVM4_MASK GENMASK(21, 16) +#define RCC_PLL4CFGR1_DIVM4_SHIFT 16 +#define RCC_PLL4CFGR1_IFRGE_MASK GENMASK(25, 24) +#define RCC_PLL4CFGR1_IFRGE_SHIFT 24 + +/* RCC_PLL4CFGR2 register fields */ +#define RCC_PLL4CFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLL4CFGR2_DIVP_SHIFT 0 +#define RCC_PLL4CFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLL4CFGR2_DIVQ_SHIFT 8 +#define RCC_PLL4CFGR2_DIVR_MASK GENMASK(22, 16) +#define RCC_PLL4CFGR2_DIVR_SHIFT 16 + +/* RCC_PLL4FRACR register fields */ +#define RCC_PLL4FRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLL4FRACR_FRACV_SHIFT 3 +#define RCC_PLL4FRACR_FRACLE BIT(16) + +/* RCC_PLL4CSGR register fields */ +#define RCC_PLL4CSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLL4CSGR_MOD_PER_SHIFT 0 +#define RCC_PLL4CSGR_TPDFN_DIS BIT(13) +#define RCC_PLL4CSGR_RPDFN_DIS BIT(14) +#define RCC_PLL4CSGR_SSCG_MODE BIT(15) +#define RCC_PLL4CSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLL4CSGR_INC_STEP_SHIFT 16 + /* RCC_I2C12CKSELR register fields */ #define RCC_I2C12CKSELR_I2C12SRC_MASK GENMASK(2, 0) #define RCC_I2C12CKSELR_I2C12SRC_SHIFT 0 @@ -520,11 +1170,40 @@ #define RCC_I2C35CKSELR_I2C35SRC_MASK GENMASK(2, 0) #define RCC_I2C35CKSELR_I2C35SRC_SHIFT 0 +/* RCC_SAI1CKSELR register fields */ +#define RCC_SAI1CKSELR_SAI1SRC_MASK GENMASK(2, 0) +#define RCC_SAI1CKSELR_SAI1SRC_SHIFT 0 + +/* RCC_SAI2CKSELR register fields */ +#define RCC_SAI2CKSELR_SAI2SRC_MASK GENMASK(2, 0) +#define RCC_SAI2CKSELR_SAI2SRC_SHIFT 0 + +/* RCC_SAI3CKSELR register fields */ +#define RCC_SAI3CKSELR_SAI3SRC_MASK GENMASK(2, 0) +#define RCC_SAI3CKSELR_SAI3SRC_SHIFT 0 + +/* RCC_SAI4CKSELR register fields */ +#define RCC_SAI4CKSELR_SAI4SRC_MASK GENMASK(2, 0) +#define RCC_SAI4CKSELR_SAI4SRC_SHIFT 0 + +/* RCC_SPI2S1CKSELR register fields */ +#define RCC_SPI2S1CKSELR_SPI1SRC_MASK GENMASK(2, 0) +#define RCC_SPI2S1CKSELR_SPI1SRC_SHIFT 0 + +/* RCC_SPI2S23CKSELR register fields */ +#define RCC_SPI2S23CKSELR_SPI23SRC_MASK GENMASK(2, 0) +#define RCC_SPI2S23CKSELR_SPI23SRC_SHIFT 0 + +/* RCC_SPI45CKSELR register fields */ +#define RCC_SPI45CKSELR_SPI45SRC_MASK GENMASK(2, 0) +#define RCC_SPI45CKSELR_SPI45SRC_SHIFT 0 + /* RCC_UART6CKSELR register fields */ #define RCC_UART6CKSELR_UART6SRC_MASK GENMASK(2, 0) #define RCC_UART6CKSELR_UART6SRC_SHIFT 0 /* RCC_UART24CKSELR register fields */ +#define RCC_UART24CKSELR_HSI 0x00000002 #define RCC_UART24CKSELR_UART24SRC_MASK GENMASK(2, 0) #define RCC_UART24CKSELR_UART24SRC_SHIFT 0 @@ -547,6 +1226,8 @@ /* RCC_ETHCKSELR register fields */ #define RCC_ETHCKSELR_ETHSRC_MASK GENMASK(1, 0) #define RCC_ETHCKSELR_ETHSRC_SHIFT 0 +#define RCC_ETHCKSELR_ETHPTPDIV_MASK GENMASK(7, 4) +#define RCC_ETHCKSELR_ETHPTPDIV_SHIFT 4 /* RCC_QSPICKSELR register fields */ #define RCC_QSPICKSELR_QSPISRC_MASK GENMASK(1, 0) @@ -556,10 +1237,1092 @@ #define RCC_FMCCKSELR_FMCSRC_MASK GENMASK(1, 0) #define RCC_FMCCKSELR_FMCSRC_SHIFT 0 +/* RCC_FDCANCKSELR register fields */ +#define RCC_FDCANCKSELR_FDCANSRC_MASK GENMASK(1, 0) +#define RCC_FDCANCKSELR_FDCANSRC_SHIFT 0 + +/* RCC_SPDIFCKSELR register fields */ +#define RCC_SPDIFCKSELR_SPDIFSRC_MASK GENMASK(1, 0) +#define RCC_SPDIFCKSELR_SPDIFSRC_SHIFT 0 + +/* RCC_CECCKSELR register fields */ +#define RCC_CECCKSELR_CECSRC_MASK GENMASK(1, 0) +#define RCC_CECCKSELR_CECSRC_SHIFT 0 + /* RCC_USBCKSELR register fields */ #define RCC_USBCKSELR_USBPHYSRC_MASK GENMASK(1, 0) #define RCC_USBCKSELR_USBPHYSRC_SHIFT 0 +#define RCC_USBCKSELR_USBOSRC BIT(4) #define RCC_USBCKSELR_USBOSRC_MASK BIT(4) #define RCC_USBCKSELR_USBOSRC_SHIFT 4 +/* RCC_RNG2CKSELR register fields */ +#define RCC_RNG2CKSELR_RNG2SRC_MASK GENMASK(1, 0) +#define RCC_RNG2CKSELR_RNG2SRC_SHIFT 0 + +/* RCC_DSICKSELR register fields */ +#define RCC_DSICKSELR_DSISRC BIT(0) + +/* RCC_ADCCKSELR register fields */ +#define RCC_ADCCKSELR_ADCSRC_MASK GENMASK(1, 0) +#define RCC_ADCCKSELR_ADCSRC_SHIFT 0 + +/* RCC_LPTIM45CKSELR register fields */ +#define RCC_LPTIM45CKSELR_LPTIM45SRC_MASK GENMASK(2, 0) +#define RCC_LPTIM45CKSELR_LPTIM45SRC_SHIFT 0 + +/* RCC_LPTIM23CKSELR register fields */ +#define RCC_LPTIM23CKSELR_LPTIM23SRC_MASK GENMASK(2, 0) +#define RCC_LPTIM23CKSELR_LPTIM23SRC_SHIFT 0 + +/* RCC_LPTIM1CKSELR register fields */ +#define RCC_LPTIM1CKSELR_LPTIM1SRC_MASK GENMASK(2, 0) +#define RCC_LPTIM1CKSELR_LPTIM1SRC_SHIFT 0 + +/* RCC_APB1RSTSETR register fields */ +#define RCC_APB1RSTSETR_TIM2RST BIT(0) +#define RCC_APB1RSTSETR_TIM3RST BIT(1) +#define RCC_APB1RSTSETR_TIM4RST BIT(2) +#define RCC_APB1RSTSETR_TIM5RST BIT(3) +#define RCC_APB1RSTSETR_TIM6RST BIT(4) +#define RCC_APB1RSTSETR_TIM7RST BIT(5) +#define RCC_APB1RSTSETR_TIM12RST BIT(6) +#define RCC_APB1RSTSETR_TIM13RST BIT(7) +#define RCC_APB1RSTSETR_TIM14RST BIT(8) +#define RCC_APB1RSTSETR_LPTIM1RST BIT(9) +#define RCC_APB1RSTSETR_SPI2RST BIT(11) +#define RCC_APB1RSTSETR_SPI3RST BIT(12) +#define RCC_APB1RSTSETR_USART2RST BIT(14) +#define RCC_APB1RSTSETR_USART3RST BIT(15) +#define RCC_APB1RSTSETR_UART4RST BIT(16) +#define RCC_APB1RSTSETR_UART5RST BIT(17) +#define RCC_APB1RSTSETR_UART7RST BIT(18) +#define RCC_APB1RSTSETR_UART8RST BIT(19) +#define RCC_APB1RSTSETR_I2C1RST BIT(21) +#define RCC_APB1RSTSETR_I2C2RST BIT(22) +#define RCC_APB1RSTSETR_I2C3RST BIT(23) +#define RCC_APB1RSTSETR_I2C5RST BIT(24) +#define RCC_APB1RSTSETR_SPDIFRST BIT(26) +#define RCC_APB1RSTSETR_CECRST BIT(27) +#define RCC_APB1RSTSETR_DAC12RST BIT(29) +#define RCC_APB1RSTSETR_MDIOSRST BIT(31) + +/* RCC_APB1RSTCLRR register fields */ +#define RCC_APB1RSTCLRR_TIM2RST BIT(0) +#define RCC_APB1RSTCLRR_TIM3RST BIT(1) +#define RCC_APB1RSTCLRR_TIM4RST BIT(2) +#define RCC_APB1RSTCLRR_TIM5RST BIT(3) +#define RCC_APB1RSTCLRR_TIM6RST BIT(4) +#define RCC_APB1RSTCLRR_TIM7RST BIT(5) +#define RCC_APB1RSTCLRR_TIM12RST BIT(6) +#define RCC_APB1RSTCLRR_TIM13RST BIT(7) +#define RCC_APB1RSTCLRR_TIM14RST BIT(8) +#define RCC_APB1RSTCLRR_LPTIM1RST BIT(9) +#define RCC_APB1RSTCLRR_SPI2RST BIT(11) +#define RCC_APB1RSTCLRR_SPI3RST BIT(12) +#define RCC_APB1RSTCLRR_USART2RST BIT(14) +#define RCC_APB1RSTCLRR_USART3RST BIT(15) +#define RCC_APB1RSTCLRR_UART4RST BIT(16) +#define RCC_APB1RSTCLRR_UART5RST BIT(17) +#define RCC_APB1RSTCLRR_UART7RST BIT(18) +#define RCC_APB1RSTCLRR_UART8RST BIT(19) +#define RCC_APB1RSTCLRR_I2C1RST BIT(21) +#define RCC_APB1RSTCLRR_I2C2RST BIT(22) +#define RCC_APB1RSTCLRR_I2C3RST BIT(23) +#define RCC_APB1RSTCLRR_I2C5RST BIT(24) +#define RCC_APB1RSTCLRR_SPDIFRST BIT(26) +#define RCC_APB1RSTCLRR_CECRST BIT(27) +#define RCC_APB1RSTCLRR_DAC12RST BIT(29) +#define RCC_APB1RSTCLRR_MDIOSRST BIT(31) + +/* RCC_APB2RSTSETR register fields */ +#define RCC_APB2RSTSETR_TIM1RST BIT(0) +#define RCC_APB2RSTSETR_TIM8RST BIT(1) +#define RCC_APB2RSTSETR_TIM15RST BIT(2) +#define RCC_APB2RSTSETR_TIM16RST BIT(3) +#define RCC_APB2RSTSETR_TIM17RST BIT(4) +#define RCC_APB2RSTSETR_SPI1RST BIT(8) +#define RCC_APB2RSTSETR_SPI4RST BIT(9) +#define RCC_APB2RSTSETR_SPI5RST BIT(10) +#define RCC_APB2RSTSETR_USART6RST BIT(13) +#define RCC_APB2RSTSETR_SAI1RST BIT(16) +#define RCC_APB2RSTSETR_SAI2RST BIT(17) +#define RCC_APB2RSTSETR_SAI3RST BIT(18) +#define RCC_APB2RSTSETR_DFSDMRST BIT(20) +#define RCC_APB2RSTSETR_FDCANRST BIT(24) + +/* RCC_APB2RSTCLRR register fields */ +#define RCC_APB2RSTCLRR_TIM1RST BIT(0) +#define RCC_APB2RSTCLRR_TIM8RST BIT(1) +#define RCC_APB2RSTCLRR_TIM15RST BIT(2) +#define RCC_APB2RSTCLRR_TIM16RST BIT(3) +#define RCC_APB2RSTCLRR_TIM17RST BIT(4) +#define RCC_APB2RSTCLRR_SPI1RST BIT(8) +#define RCC_APB2RSTCLRR_SPI4RST BIT(9) +#define RCC_APB2RSTCLRR_SPI5RST BIT(10) +#define RCC_APB2RSTCLRR_USART6RST BIT(13) +#define RCC_APB2RSTCLRR_SAI1RST BIT(16) +#define RCC_APB2RSTCLRR_SAI2RST BIT(17) +#define RCC_APB2RSTCLRR_SAI3RST BIT(18) +#define RCC_APB2RSTCLRR_DFSDMRST BIT(20) +#define RCC_APB2RSTCLRR_FDCANRST BIT(24) + +/* RCC_APB3RSTSETR register fields */ +#define RCC_APB3RSTSETR_LPTIM2RST BIT(0) +#define RCC_APB3RSTSETR_LPTIM3RST BIT(1) +#define RCC_APB3RSTSETR_LPTIM4RST BIT(2) +#define RCC_APB3RSTSETR_LPTIM5RST BIT(3) +#define RCC_APB3RSTSETR_SAI4RST BIT(8) +#define RCC_APB3RSTSETR_SYSCFGRST BIT(11) +#define RCC_APB3RSTSETR_VREFRST BIT(13) +#define RCC_APB3RSTSETR_TMPSENSRST BIT(16) +#define RCC_APB3RSTSETR_PMBCTRLRST BIT(17) + +/* RCC_APB3RSTCLRR register fields */ +#define RCC_APB3RSTCLRR_LPTIM2RST BIT(0) +#define RCC_APB3RSTCLRR_LPTIM3RST BIT(1) +#define RCC_APB3RSTCLRR_LPTIM4RST BIT(2) +#define RCC_APB3RSTCLRR_LPTIM5RST BIT(3) +#define RCC_APB3RSTCLRR_SAI4RST BIT(8) +#define RCC_APB3RSTCLRR_SYSCFGRST BIT(11) +#define RCC_APB3RSTCLRR_VREFRST BIT(13) +#define RCC_APB3RSTCLRR_TMPSENSRST BIT(16) +#define RCC_APB3RSTCLRR_PMBCTRLRST BIT(17) + +/* RCC_AHB2RSTSETR register fields */ +#define RCC_AHB2RSTSETR_DMA1RST BIT(0) +#define RCC_AHB2RSTSETR_DMA2RST BIT(1) +#define RCC_AHB2RSTSETR_DMAMUXRST BIT(2) +#define RCC_AHB2RSTSETR_ADC12RST BIT(5) +#define RCC_AHB2RSTSETR_USBORST BIT(8) +#define RCC_AHB2RSTSETR_SDMMC3RST BIT(16) + +/* RCC_AHB2RSTCLRR register fields */ +#define RCC_AHB2RSTCLRR_DMA1RST BIT(0) +#define RCC_AHB2RSTCLRR_DMA2RST BIT(1) +#define RCC_AHB2RSTCLRR_DMAMUXRST BIT(2) +#define RCC_AHB2RSTCLRR_ADC12RST BIT(5) +#define RCC_AHB2RSTCLRR_USBORST BIT(8) +#define RCC_AHB2RSTCLRR_SDMMC3RST BIT(16) + +/* RCC_AHB3RSTSETR register fields */ +#define RCC_AHB3RSTSETR_DCMIRST BIT(0) +#define RCC_AHB3RSTSETR_CRYP2RST BIT(4) +#define RCC_AHB3RSTSETR_HASH2RST BIT(5) +#define RCC_AHB3RSTSETR_RNG2RST BIT(6) +#define RCC_AHB3RSTSETR_CRC2RST BIT(7) +#define RCC_AHB3RSTSETR_HSEMRST BIT(11) +#define RCC_AHB3RSTSETR_IPCCRST BIT(12) + +/* RCC_AHB3RSTCLRR register fields */ +#define RCC_AHB3RSTCLRR_DCMIRST BIT(0) +#define RCC_AHB3RSTCLRR_CRYP2RST BIT(4) +#define RCC_AHB3RSTCLRR_HASH2RST BIT(5) +#define RCC_AHB3RSTCLRR_RNG2RST BIT(6) +#define RCC_AHB3RSTCLRR_CRC2RST BIT(7) +#define RCC_AHB3RSTCLRR_HSEMRST BIT(11) +#define RCC_AHB3RSTCLRR_IPCCRST BIT(12) + +/* RCC_AHB4RSTSETR register fields */ +#define RCC_AHB4RSTSETR_GPIOARST BIT(0) +#define RCC_AHB4RSTSETR_GPIOBRST BIT(1) +#define RCC_AHB4RSTSETR_GPIOCRST BIT(2) +#define RCC_AHB4RSTSETR_GPIODRST BIT(3) +#define RCC_AHB4RSTSETR_GPIOERST BIT(4) +#define RCC_AHB4RSTSETR_GPIOFRST BIT(5) +#define RCC_AHB4RSTSETR_GPIOGRST BIT(6) +#define RCC_AHB4RSTSETR_GPIOHRST BIT(7) +#define RCC_AHB4RSTSETR_GPIOIRST BIT(8) +#define RCC_AHB4RSTSETR_GPIOJRST BIT(9) +#define RCC_AHB4RSTSETR_GPIOKRST BIT(10) + +/* RCC_AHB4RSTCLRR register fields */ +#define RCC_AHB4RSTCLRR_GPIOARST BIT(0) +#define RCC_AHB4RSTCLRR_GPIOBRST BIT(1) +#define RCC_AHB4RSTCLRR_GPIOCRST BIT(2) +#define RCC_AHB4RSTCLRR_GPIODRST BIT(3) +#define RCC_AHB4RSTCLRR_GPIOERST BIT(4) +#define RCC_AHB4RSTCLRR_GPIOFRST BIT(5) +#define RCC_AHB4RSTCLRR_GPIOGRST BIT(6) +#define RCC_AHB4RSTCLRR_GPIOHRST BIT(7) +#define RCC_AHB4RSTCLRR_GPIOIRST BIT(8) +#define RCC_AHB4RSTCLRR_GPIOJRST BIT(9) +#define RCC_AHB4RSTCLRR_GPIOKRST BIT(10) + +/* RCC_MP_APB1ENSETR register fields */ +#define RCC_MP_APB1ENSETR_TIM2EN BIT(0) +#define RCC_MP_APB1ENSETR_TIM3EN BIT(1) +#define RCC_MP_APB1ENSETR_TIM4EN BIT(2) +#define RCC_MP_APB1ENSETR_TIM5EN BIT(3) +#define RCC_MP_APB1ENSETR_TIM6EN BIT(4) +#define RCC_MP_APB1ENSETR_TIM7EN BIT(5) +#define RCC_MP_APB1ENSETR_TIM12EN BIT(6) +#define RCC_MP_APB1ENSETR_TIM13EN BIT(7) +#define RCC_MP_APB1ENSETR_TIM14EN BIT(8) +#define RCC_MP_APB1ENSETR_LPTIM1EN BIT(9) +#define RCC_MP_APB1ENSETR_SPI2EN BIT(11) +#define RCC_MP_APB1ENSETR_SPI3EN BIT(12) +#define RCC_MP_APB1ENSETR_USART2EN BIT(14) +#define RCC_MP_APB1ENSETR_USART3EN BIT(15) +#define RCC_MP_APB1ENSETR_UART4EN BIT(16) +#define RCC_MP_APB1ENSETR_UART5EN BIT(17) +#define RCC_MP_APB1ENSETR_UART7EN BIT(18) +#define RCC_MP_APB1ENSETR_UART8EN BIT(19) +#define RCC_MP_APB1ENSETR_I2C1EN BIT(21) +#define RCC_MP_APB1ENSETR_I2C2EN BIT(22) +#define RCC_MP_APB1ENSETR_I2C3EN BIT(23) +#define RCC_MP_APB1ENSETR_I2C5EN BIT(24) +#define RCC_MP_APB1ENSETR_SPDIFEN BIT(26) +#define RCC_MP_APB1ENSETR_CECEN BIT(27) +#define RCC_MP_APB1ENSETR_DAC12EN BIT(29) +#define RCC_MP_APB1ENSETR_MDIOSEN BIT(31) + +/* RCC_MP_APB1ENCLRR register fields */ +#define RCC_MP_APB1ENCLRR_TIM2EN BIT(0) +#define RCC_MP_APB1ENCLRR_TIM3EN BIT(1) +#define RCC_MP_APB1ENCLRR_TIM4EN BIT(2) +#define RCC_MP_APB1ENCLRR_TIM5EN BIT(3) +#define RCC_MP_APB1ENCLRR_TIM6EN BIT(4) +#define RCC_MP_APB1ENCLRR_TIM7EN BIT(5) +#define RCC_MP_APB1ENCLRR_TIM12EN BIT(6) +#define RCC_MP_APB1ENCLRR_TIM13EN BIT(7) +#define RCC_MP_APB1ENCLRR_TIM14EN BIT(8) +#define RCC_MP_APB1ENCLRR_LPTIM1EN BIT(9) +#define RCC_MP_APB1ENCLRR_SPI2EN BIT(11) +#define RCC_MP_APB1ENCLRR_SPI3EN BIT(12) +#define RCC_MP_APB1ENCLRR_USART2EN BIT(14) +#define RCC_MP_APB1ENCLRR_USART3EN BIT(15) +#define RCC_MP_APB1ENCLRR_UART4EN BIT(16) +#define RCC_MP_APB1ENCLRR_UART5EN BIT(17) +#define RCC_MP_APB1ENCLRR_UART7EN BIT(18) +#define RCC_MP_APB1ENCLRR_UART8EN BIT(19) +#define RCC_MP_APB1ENCLRR_I2C1EN BIT(21) +#define RCC_MP_APB1ENCLRR_I2C2EN BIT(22) +#define RCC_MP_APB1ENCLRR_I2C3EN BIT(23) +#define RCC_MP_APB1ENCLRR_I2C5EN BIT(24) +#define RCC_MP_APB1ENCLRR_SPDIFEN BIT(26) +#define RCC_MP_APB1ENCLRR_CECEN BIT(27) +#define RCC_MP_APB1ENCLRR_DAC12EN BIT(29) +#define RCC_MP_APB1ENCLRR_MDIOSEN BIT(31) + +/* RCC_MP_APB2ENSETR register fields */ +#define RCC_MP_APB2ENSETR_TIM1EN BIT(0) +#define RCC_MP_APB2ENSETR_TIM8EN BIT(1) +#define RCC_MP_APB2ENSETR_TIM15EN BIT(2) +#define RCC_MP_APB2ENSETR_TIM16EN BIT(3) +#define RCC_MP_APB2ENSETR_TIM17EN BIT(4) +#define RCC_MP_APB2ENSETR_SPI1EN BIT(8) +#define RCC_MP_APB2ENSETR_SPI4EN BIT(9) +#define RCC_MP_APB2ENSETR_SPI5EN BIT(10) +#define RCC_MP_APB2ENSETR_USART6EN BIT(13) +#define RCC_MP_APB2ENSETR_SAI1EN BIT(16) +#define RCC_MP_APB2ENSETR_SAI2EN BIT(17) +#define RCC_MP_APB2ENSETR_SAI3EN BIT(18) +#define RCC_MP_APB2ENSETR_DFSDMEN BIT(20) +#define RCC_MP_APB2ENSETR_ADFSDMEN BIT(21) +#define RCC_MP_APB2ENSETR_FDCANEN BIT(24) + +/* RCC_MP_APB2ENCLRR register fields */ +#define RCC_MP_APB2ENCLRR_TIM1EN BIT(0) +#define RCC_MP_APB2ENCLRR_TIM8EN BIT(1) +#define RCC_MP_APB2ENCLRR_TIM15EN BIT(2) +#define RCC_MP_APB2ENCLRR_TIM16EN BIT(3) +#define RCC_MP_APB2ENCLRR_TIM17EN BIT(4) +#define RCC_MP_APB2ENCLRR_SPI1EN BIT(8) +#define RCC_MP_APB2ENCLRR_SPI4EN BIT(9) +#define RCC_MP_APB2ENCLRR_SPI5EN BIT(10) +#define RCC_MP_APB2ENCLRR_USART6EN BIT(13) +#define RCC_MP_APB2ENCLRR_SAI1EN BIT(16) +#define RCC_MP_APB2ENCLRR_SAI2EN BIT(17) +#define RCC_MP_APB2ENCLRR_SAI3EN BIT(18) +#define RCC_MP_APB2ENCLRR_DFSDMEN BIT(20) +#define RCC_MP_APB2ENCLRR_ADFSDMEN BIT(21) +#define RCC_MP_APB2ENCLRR_FDCANEN BIT(24) + +/* RCC_MP_APB3ENSETR register fields */ +#define RCC_MP_APB3ENSETR_LPTIM2EN BIT(0) +#define RCC_MP_APB3ENSETR_LPTIM3EN BIT(1) +#define RCC_MP_APB3ENSETR_LPTIM4EN BIT(2) +#define RCC_MP_APB3ENSETR_LPTIM5EN BIT(3) +#define RCC_MP_APB3ENSETR_SAI4EN BIT(8) +#define RCC_MP_APB3ENSETR_SYSCFGEN BIT(11) +#define RCC_MP_APB3ENSETR_VREFEN BIT(13) +#define RCC_MP_APB3ENSETR_TMPSENSEN BIT(16) +#define RCC_MP_APB3ENSETR_PMBCTRLEN BIT(17) +#define RCC_MP_APB3ENSETR_HDPEN BIT(20) + +/* RCC_MP_APB3ENCLRR register fields */ +#define RCC_MP_APB3ENCLRR_LPTIM2EN BIT(0) +#define RCC_MP_APB3ENCLRR_LPTIM3EN BIT(1) +#define RCC_MP_APB3ENCLRR_LPTIM4EN BIT(2) +#define RCC_MP_APB3ENCLRR_LPTIM5EN BIT(3) +#define RCC_MP_APB3ENCLRR_SAI4EN BIT(8) +#define RCC_MP_APB3ENCLRR_SYSCFGEN BIT(11) +#define RCC_MP_APB3ENCLRR_VREFEN BIT(13) +#define RCC_MP_APB3ENCLRR_TMPSENSEN BIT(16) +#define RCC_MP_APB3ENCLRR_PMBCTRLEN BIT(17) +#define RCC_MP_APB3ENCLRR_HDPEN BIT(20) + +/* RCC_MP_AHB2ENSETR register fields */ +#define RCC_MP_AHB2ENSETR_DMA1EN BIT(0) +#define RCC_MP_AHB2ENSETR_DMA2EN BIT(1) +#define RCC_MP_AHB2ENSETR_DMAMUXEN BIT(2) +#define RCC_MP_AHB2ENSETR_ADC12EN BIT(5) +#define RCC_MP_AHB2ENSETR_USBOEN BIT(8) +#define RCC_MP_AHB2ENSETR_SDMMC3EN BIT(16) + +/* RCC_MP_AHB2ENCLRR register fields */ +#define RCC_MP_AHB2ENCLRR_DMA1EN BIT(0) +#define RCC_MP_AHB2ENCLRR_DMA2EN BIT(1) +#define RCC_MP_AHB2ENCLRR_DMAMUXEN BIT(2) +#define RCC_MP_AHB2ENCLRR_ADC12EN BIT(5) +#define RCC_MP_AHB2ENCLRR_USBOEN BIT(8) +#define RCC_MP_AHB2ENCLRR_SDMMC3EN BIT(16) + +/* RCC_MP_AHB3ENSETR register fields */ +#define RCC_MP_AHB3ENSETR_DCMIEN BIT(0) +#define RCC_MP_AHB3ENSETR_CRYP2EN BIT(4) +#define RCC_MP_AHB3ENSETR_HASH2EN BIT(5) +#define RCC_MP_AHB3ENSETR_RNG2EN BIT(6) +#define RCC_MP_AHB3ENSETR_CRC2EN BIT(7) +#define RCC_MP_AHB3ENSETR_HSEMEN BIT(11) +#define RCC_MP_AHB3ENSETR_IPCCEN BIT(12) + +/* RCC_MP_AHB3ENCLRR register fields */ +#define RCC_MP_AHB3ENCLRR_DCMIEN BIT(0) +#define RCC_MP_AHB3ENCLRR_CRYP2EN BIT(4) +#define RCC_MP_AHB3ENCLRR_HASH2EN BIT(5) +#define RCC_MP_AHB3ENCLRR_RNG2EN BIT(6) +#define RCC_MP_AHB3ENCLRR_CRC2EN BIT(7) +#define RCC_MP_AHB3ENCLRR_HSEMEN BIT(11) +#define RCC_MP_AHB3ENCLRR_IPCCEN BIT(12) + +/* RCC_MP_AHB4ENSETR register fields */ +#define RCC_MP_AHB4ENSETR_GPIOAEN BIT(0) +#define RCC_MP_AHB4ENSETR_GPIOBEN BIT(1) +#define RCC_MP_AHB4ENSETR_GPIOCEN BIT(2) +#define RCC_MP_AHB4ENSETR_GPIODEN BIT(3) +#define RCC_MP_AHB4ENSETR_GPIOEEN BIT(4) +#define RCC_MP_AHB4ENSETR_GPIOFEN BIT(5) +#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6) +#define RCC_MP_AHB4ENSETR_GPIOHEN BIT(7) +#define RCC_MP_AHB4ENSETR_GPIOIEN BIT(8) +#define RCC_MP_AHB4ENSETR_GPIOJEN BIT(9) +#define RCC_MP_AHB4ENSETR_GPIOKEN BIT(10) + +/* RCC_MP_AHB4ENCLRR register fields */ +#define RCC_MP_AHB4ENCLRR_GPIOAEN BIT(0) +#define RCC_MP_AHB4ENCLRR_GPIOBEN BIT(1) +#define RCC_MP_AHB4ENCLRR_GPIOCEN BIT(2) +#define RCC_MP_AHB4ENCLRR_GPIODEN BIT(3) +#define RCC_MP_AHB4ENCLRR_GPIOEEN BIT(4) +#define RCC_MP_AHB4ENCLRR_GPIOFEN BIT(5) +#define RCC_MP_AHB4ENCLRR_GPIOGEN BIT(6) +#define RCC_MP_AHB4ENCLRR_GPIOHEN BIT(7) +#define RCC_MP_AHB4ENCLRR_GPIOIEN BIT(8) +#define RCC_MP_AHB4ENCLRR_GPIOJEN BIT(9) +#define RCC_MP_AHB4ENCLRR_GPIOKEN BIT(10) + +/* RCC_MP_MLAHBENSETR register fields */ +#define RCC_MP_MLAHBENSETR_RETRAMEN BIT(4) + +/* RCC_MP_MLAHBENCLRR register fields */ +#define RCC_MP_MLAHBENCLRR_RETRAMEN BIT(4) + +/* RCC_MC_APB1ENSETR register fields */ +#define RCC_MC_APB1ENSETR_TIM2EN BIT(0) +#define RCC_MC_APB1ENSETR_TIM3EN BIT(1) +#define RCC_MC_APB1ENSETR_TIM4EN BIT(2) +#define RCC_MC_APB1ENSETR_TIM5EN BIT(3) +#define RCC_MC_APB1ENSETR_TIM6EN BIT(4) +#define RCC_MC_APB1ENSETR_TIM7EN BIT(5) +#define RCC_MC_APB1ENSETR_TIM12EN BIT(6) +#define RCC_MC_APB1ENSETR_TIM13EN BIT(7) +#define RCC_MC_APB1ENSETR_TIM14EN BIT(8) +#define RCC_MC_APB1ENSETR_LPTIM1EN BIT(9) +#define RCC_MC_APB1ENSETR_SPI2EN BIT(11) +#define RCC_MC_APB1ENSETR_SPI3EN BIT(12) +#define RCC_MC_APB1ENSETR_USART2EN BIT(14) +#define RCC_MC_APB1ENSETR_USART3EN BIT(15) +#define RCC_MC_APB1ENSETR_UART4EN BIT(16) +#define RCC_MC_APB1ENSETR_UART5EN BIT(17) +#define RCC_MC_APB1ENSETR_UART7EN BIT(18) +#define RCC_MC_APB1ENSETR_UART8EN BIT(19) +#define RCC_MC_APB1ENSETR_I2C1EN BIT(21) +#define RCC_MC_APB1ENSETR_I2C2EN BIT(22) +#define RCC_MC_APB1ENSETR_I2C3EN BIT(23) +#define RCC_MC_APB1ENSETR_I2C5EN BIT(24) +#define RCC_MC_APB1ENSETR_SPDIFEN BIT(26) +#define RCC_MC_APB1ENSETR_CECEN BIT(27) +#define RCC_MC_APB1ENSETR_WWDG1EN BIT(28) +#define RCC_MC_APB1ENSETR_DAC12EN BIT(29) +#define RCC_MC_APB1ENSETR_MDIOSEN BIT(31) + +/* RCC_MC_APB1ENCLRR register fields */ +#define RCC_MC_APB1ENCLRR_TIM2EN BIT(0) +#define RCC_MC_APB1ENCLRR_TIM3EN BIT(1) +#define RCC_MC_APB1ENCLRR_TIM4EN BIT(2) +#define RCC_MC_APB1ENCLRR_TIM5EN BIT(3) +#define RCC_MC_APB1ENCLRR_TIM6EN BIT(4) +#define RCC_MC_APB1ENCLRR_TIM7EN BIT(5) +#define RCC_MC_APB1ENCLRR_TIM12EN BIT(6) +#define RCC_MC_APB1ENCLRR_TIM13EN BIT(7) +#define RCC_MC_APB1ENCLRR_TIM14EN BIT(8) +#define RCC_MC_APB1ENCLRR_LPTIM1EN BIT(9) +#define RCC_MC_APB1ENCLRR_SPI2EN BIT(11) +#define RCC_MC_APB1ENCLRR_SPI3EN BIT(12) +#define RCC_MC_APB1ENCLRR_USART2EN BIT(14) +#define RCC_MC_APB1ENCLRR_USART3EN BIT(15) +#define RCC_MC_APB1ENCLRR_UART4EN BIT(16) +#define RCC_MC_APB1ENCLRR_UART5EN BIT(17) +#define RCC_MC_APB1ENCLRR_UART7EN BIT(18) +#define RCC_MC_APB1ENCLRR_UART8EN BIT(19) +#define RCC_MC_APB1ENCLRR_I2C1EN BIT(21) +#define RCC_MC_APB1ENCLRR_I2C2EN BIT(22) +#define RCC_MC_APB1ENCLRR_I2C3EN BIT(23) +#define RCC_MC_APB1ENCLRR_I2C5EN BIT(24) +#define RCC_MC_APB1ENCLRR_SPDIFEN BIT(26) +#define RCC_MC_APB1ENCLRR_CECEN BIT(27) +#define RCC_MC_APB1ENCLRR_DAC12EN BIT(29) +#define RCC_MC_APB1ENCLRR_MDIOSEN BIT(31) + +/* RCC_MC_APB2ENSETR register fields */ +#define RCC_MC_APB2ENSETR_TIM1EN BIT(0) +#define RCC_MC_APB2ENSETR_TIM8EN BIT(1) +#define RCC_MC_APB2ENSETR_TIM15EN BIT(2) +#define RCC_MC_APB2ENSETR_TIM16EN BIT(3) +#define RCC_MC_APB2ENSETR_TIM17EN BIT(4) +#define RCC_MC_APB2ENSETR_SPI1EN BIT(8) +#define RCC_MC_APB2ENSETR_SPI4EN BIT(9) +#define RCC_MC_APB2ENSETR_SPI5EN BIT(10) +#define RCC_MC_APB2ENSETR_USART6EN BIT(13) +#define RCC_MC_APB2ENSETR_SAI1EN BIT(16) +#define RCC_MC_APB2ENSETR_SAI2EN BIT(17) +#define RCC_MC_APB2ENSETR_SAI3EN BIT(18) +#define RCC_MC_APB2ENSETR_DFSDMEN BIT(20) +#define RCC_MC_APB2ENSETR_ADFSDMEN BIT(21) +#define RCC_MC_APB2ENSETR_FDCANEN BIT(24) + +/* RCC_MC_APB2ENCLRR register fields */ +#define RCC_MC_APB2ENCLRR_TIM1EN BIT(0) +#define RCC_MC_APB2ENCLRR_TIM8EN BIT(1) +#define RCC_MC_APB2ENCLRR_TIM15EN BIT(2) +#define RCC_MC_APB2ENCLRR_TIM16EN BIT(3) +#define RCC_MC_APB2ENCLRR_TIM17EN BIT(4) +#define RCC_MC_APB2ENCLRR_SPI1EN BIT(8) +#define RCC_MC_APB2ENCLRR_SPI4EN BIT(9) +#define RCC_MC_APB2ENCLRR_SPI5EN BIT(10) +#define RCC_MC_APB2ENCLRR_USART6EN BIT(13) +#define RCC_MC_APB2ENCLRR_SAI1EN BIT(16) +#define RCC_MC_APB2ENCLRR_SAI2EN BIT(17) +#define RCC_MC_APB2ENCLRR_SAI3EN BIT(18) +#define RCC_MC_APB2ENCLRR_DFSDMEN BIT(20) +#define RCC_MC_APB2ENCLRR_ADFSDMEN BIT(21) +#define RCC_MC_APB2ENCLRR_FDCANEN BIT(24) + +/* RCC_MC_APB3ENSETR register fields */ +#define RCC_MC_APB3ENSETR_LPTIM2EN BIT(0) +#define RCC_MC_APB3ENSETR_LPTIM3EN BIT(1) +#define RCC_MC_APB3ENSETR_LPTIM4EN BIT(2) +#define RCC_MC_APB3ENSETR_LPTIM5EN BIT(3) +#define RCC_MC_APB3ENSETR_SAI4EN BIT(8) +#define RCC_MC_APB3ENSETR_SYSCFGEN BIT(11) +#define RCC_MC_APB3ENSETR_VREFEN BIT(13) +#define RCC_MC_APB3ENSETR_TMPSENSEN BIT(16) +#define RCC_MC_APB3ENSETR_PMBCTRLEN BIT(17) +#define RCC_MC_APB3ENSETR_HDPEN BIT(20) + +/* RCC_MC_APB3ENCLRR register fields */ +#define RCC_MC_APB3ENCLRR_LPTIM2EN BIT(0) +#define RCC_MC_APB3ENCLRR_LPTIM3EN BIT(1) +#define RCC_MC_APB3ENCLRR_LPTIM4EN BIT(2) +#define RCC_MC_APB3ENCLRR_LPTIM5EN BIT(3) +#define RCC_MC_APB3ENCLRR_SAI4EN BIT(8) +#define RCC_MC_APB3ENCLRR_SYSCFGEN BIT(11) +#define RCC_MC_APB3ENCLRR_VREFEN BIT(13) +#define RCC_MC_APB3ENCLRR_TMPSENSEN BIT(16) +#define RCC_MC_APB3ENCLRR_PMBCTRLEN BIT(17) +#define RCC_MC_APB3ENCLRR_HDPEN BIT(20) + +/* RCC_MC_AHB2ENSETR register fields */ +#define RCC_MC_AHB2ENSETR_DMA1EN BIT(0) +#define RCC_MC_AHB2ENSETR_DMA2EN BIT(1) +#define RCC_MC_AHB2ENSETR_DMAMUXEN BIT(2) +#define RCC_MC_AHB2ENSETR_ADC12EN BIT(5) +#define RCC_MC_AHB2ENSETR_USBOEN BIT(8) +#define RCC_MC_AHB2ENSETR_SDMMC3EN BIT(16) + +/* RCC_MC_AHB2ENCLRR register fields */ +#define RCC_MC_AHB2ENCLRR_DMA1EN BIT(0) +#define RCC_MC_AHB2ENCLRR_DMA2EN BIT(1) +#define RCC_MC_AHB2ENCLRR_DMAMUXEN BIT(2) +#define RCC_MC_AHB2ENCLRR_ADC12EN BIT(5) +#define RCC_MC_AHB2ENCLRR_USBOEN BIT(8) +#define RCC_MC_AHB2ENCLRR_SDMMC3EN BIT(16) + +/* RCC_MC_AHB3ENSETR register fields */ +#define RCC_MC_AHB3ENSETR_DCMIEN BIT(0) +#define RCC_MC_AHB3ENSETR_CRYP2EN BIT(4) +#define RCC_MC_AHB3ENSETR_HASH2EN BIT(5) +#define RCC_MC_AHB3ENSETR_RNG2EN BIT(6) +#define RCC_MC_AHB3ENSETR_CRC2EN BIT(7) +#define RCC_MC_AHB3ENSETR_HSEMEN BIT(11) +#define RCC_MC_AHB3ENSETR_IPCCEN BIT(12) + +/* RCC_MC_AHB3ENCLRR register fields */ +#define RCC_MC_AHB3ENCLRR_DCMIEN BIT(0) +#define RCC_MC_AHB3ENCLRR_CRYP2EN BIT(4) +#define RCC_MC_AHB3ENCLRR_HASH2EN BIT(5) +#define RCC_MC_AHB3ENCLRR_RNG2EN BIT(6) +#define RCC_MC_AHB3ENCLRR_CRC2EN BIT(7) +#define RCC_MC_AHB3ENCLRR_HSEMEN BIT(11) +#define RCC_MC_AHB3ENCLRR_IPCCEN BIT(12) + +/* RCC_MC_AHB4ENSETR register fields */ +#define RCC_MC_AHB4ENSETR_GPIOAEN BIT(0) +#define RCC_MC_AHB4ENSETR_GPIOBEN BIT(1) +#define RCC_MC_AHB4ENSETR_GPIOCEN BIT(2) +#define RCC_MC_AHB4ENSETR_GPIODEN BIT(3) +#define RCC_MC_AHB4ENSETR_GPIOEEN BIT(4) +#define RCC_MC_AHB4ENSETR_GPIOFEN BIT(5) +#define RCC_MC_AHB4ENSETR_GPIOGEN BIT(6) +#define RCC_MC_AHB4ENSETR_GPIOHEN BIT(7) +#define RCC_MC_AHB4ENSETR_GPIOIEN BIT(8) +#define RCC_MC_AHB4ENSETR_GPIOJEN BIT(9) +#define RCC_MC_AHB4ENSETR_GPIOKEN BIT(10) + +/* RCC_MC_AHB4ENCLRR register fields */ +#define RCC_MC_AHB4ENCLRR_GPIOAEN BIT(0) +#define RCC_MC_AHB4ENCLRR_GPIOBEN BIT(1) +#define RCC_MC_AHB4ENCLRR_GPIOCEN BIT(2) +#define RCC_MC_AHB4ENCLRR_GPIODEN BIT(3) +#define RCC_MC_AHB4ENCLRR_GPIOEEN BIT(4) +#define RCC_MC_AHB4ENCLRR_GPIOFEN BIT(5) +#define RCC_MC_AHB4ENCLRR_GPIOGEN BIT(6) +#define RCC_MC_AHB4ENCLRR_GPIOHEN BIT(7) +#define RCC_MC_AHB4ENCLRR_GPIOIEN BIT(8) +#define RCC_MC_AHB4ENCLRR_GPIOJEN BIT(9) +#define RCC_MC_AHB4ENCLRR_GPIOKEN BIT(10) + +/* RCC_MC_AXIMENSETR register fields */ +#define RCC_MC_AXIMENSETR_SYSRAMEN BIT(0) + +/* RCC_MC_AXIMENCLRR register fields */ +#define RCC_MC_AXIMENCLRR_SYSRAMEN BIT(0) + +/* RCC_MC_MLAHBENSETR register fields */ +#define RCC_MC_MLAHBENSETR_RETRAMEN BIT(4) + +/* RCC_MC_MLAHBENCLRR register fields */ +#define RCC_MC_MLAHBENCLRR_RETRAMEN BIT(4) + +/* RCC_MP_APB1LPENSETR register fields */ +#define RCC_MP_APB1LPENSETR_TIM2LPEN BIT(0) +#define RCC_MP_APB1LPENSETR_TIM3LPEN BIT(1) +#define RCC_MP_APB1LPENSETR_TIM4LPEN BIT(2) +#define RCC_MP_APB1LPENSETR_TIM5LPEN BIT(3) +#define RCC_MP_APB1LPENSETR_TIM6LPEN BIT(4) +#define RCC_MP_APB1LPENSETR_TIM7LPEN BIT(5) +#define RCC_MP_APB1LPENSETR_TIM12LPEN BIT(6) +#define RCC_MP_APB1LPENSETR_TIM13LPEN BIT(7) +#define RCC_MP_APB1LPENSETR_TIM14LPEN BIT(8) +#define RCC_MP_APB1LPENSETR_LPTIM1LPEN BIT(9) +#define RCC_MP_APB1LPENSETR_SPI2LPEN BIT(11) +#define RCC_MP_APB1LPENSETR_SPI3LPEN BIT(12) +#define RCC_MP_APB1LPENSETR_USART2LPEN BIT(14) +#define RCC_MP_APB1LPENSETR_USART3LPEN BIT(15) +#define RCC_MP_APB1LPENSETR_UART4LPEN BIT(16) +#define RCC_MP_APB1LPENSETR_UART5LPEN BIT(17) +#define RCC_MP_APB1LPENSETR_UART7LPEN BIT(18) +#define RCC_MP_APB1LPENSETR_UART8LPEN BIT(19) +#define RCC_MP_APB1LPENSETR_I2C1LPEN BIT(21) +#define RCC_MP_APB1LPENSETR_I2C2LPEN BIT(22) +#define RCC_MP_APB1LPENSETR_I2C3LPEN BIT(23) +#define RCC_MP_APB1LPENSETR_I2C5LPEN BIT(24) +#define RCC_MP_APB1LPENSETR_SPDIFLPEN BIT(26) +#define RCC_MP_APB1LPENSETR_CECLPEN BIT(27) +#define RCC_MP_APB1LPENSETR_DAC12LPEN BIT(29) +#define RCC_MP_APB1LPENSETR_MDIOSLPEN BIT(31) + +/* RCC_MP_APB1LPENCLRR register fields */ +#define RCC_MP_APB1LPENCLRR_TIM2LPEN BIT(0) +#define RCC_MP_APB1LPENCLRR_TIM3LPEN BIT(1) +#define RCC_MP_APB1LPENCLRR_TIM4LPEN BIT(2) +#define RCC_MP_APB1LPENCLRR_TIM5LPEN BIT(3) +#define RCC_MP_APB1LPENCLRR_TIM6LPEN BIT(4) +#define RCC_MP_APB1LPENCLRR_TIM7LPEN BIT(5) +#define RCC_MP_APB1LPENCLRR_TIM12LPEN BIT(6) +#define RCC_MP_APB1LPENCLRR_TIM13LPEN BIT(7) +#define RCC_MP_APB1LPENCLRR_TIM14LPEN BIT(8) +#define RCC_MP_APB1LPENCLRR_LPTIM1LPEN BIT(9) +#define RCC_MP_APB1LPENCLRR_SPI2LPEN BIT(11) +#define RCC_MP_APB1LPENCLRR_SPI3LPEN BIT(12) +#define RCC_MP_APB1LPENCLRR_USART2LPEN BIT(14) +#define RCC_MP_APB1LPENCLRR_USART3LPEN BIT(15) +#define RCC_MP_APB1LPENCLRR_UART4LPEN BIT(16) +#define RCC_MP_APB1LPENCLRR_UART5LPEN BIT(17) +#define RCC_MP_APB1LPENCLRR_UART7LPEN BIT(18) +#define RCC_MP_APB1LPENCLRR_UART8LPEN BIT(19) +#define RCC_MP_APB1LPENCLRR_I2C1LPEN BIT(21) +#define RCC_MP_APB1LPENCLRR_I2C2LPEN BIT(22) +#define RCC_MP_APB1LPENCLRR_I2C3LPEN BIT(23) +#define RCC_MP_APB1LPENCLRR_I2C5LPEN BIT(24) +#define RCC_MP_APB1LPENCLRR_SPDIFLPEN BIT(26) +#define RCC_MP_APB1LPENCLRR_CECLPEN BIT(27) +#define RCC_MP_APB1LPENCLRR_DAC12LPEN BIT(29) +#define RCC_MP_APB1LPENCLRR_MDIOSLPEN BIT(31) + +/* RCC_MP_APB2LPENSETR register fields */ +#define RCC_MP_APB2LPENSETR_TIM1LPEN BIT(0) +#define RCC_MP_APB2LPENSETR_TIM8LPEN BIT(1) +#define RCC_MP_APB2LPENSETR_TIM15LPEN BIT(2) +#define RCC_MP_APB2LPENSETR_TIM16LPEN BIT(3) +#define RCC_MP_APB2LPENSETR_TIM17LPEN BIT(4) +#define RCC_MP_APB2LPENSETR_SPI1LPEN BIT(8) +#define RCC_MP_APB2LPENSETR_SPI4LPEN BIT(9) +#define RCC_MP_APB2LPENSETR_SPI5LPEN BIT(10) +#define RCC_MP_APB2LPENSETR_USART6LPEN BIT(13) +#define RCC_MP_APB2LPENSETR_SAI1LPEN BIT(16) +#define RCC_MP_APB2LPENSETR_SAI2LPEN BIT(17) +#define RCC_MP_APB2LPENSETR_SAI3LPEN BIT(18) +#define RCC_MP_APB2LPENSETR_DFSDMLPEN BIT(20) +#define RCC_MP_APB2LPENSETR_ADFSDMLPEN BIT(21) +#define RCC_MP_APB2LPENSETR_FDCANLPEN BIT(24) + +/* RCC_MP_APB2LPENCLRR register fields */ +#define RCC_MP_APB2LPENCLRR_TIM1LPEN BIT(0) +#define RCC_MP_APB2LPENCLRR_TIM8LPEN BIT(1) +#define RCC_MP_APB2LPENCLRR_TIM15LPEN BIT(2) +#define RCC_MP_APB2LPENCLRR_TIM16LPEN BIT(3) +#define RCC_MP_APB2LPENCLRR_TIM17LPEN BIT(4) +#define RCC_MP_APB2LPENCLRR_SPI1LPEN BIT(8) +#define RCC_MP_APB2LPENCLRR_SPI4LPEN BIT(9) +#define RCC_MP_APB2LPENCLRR_SPI5LPEN BIT(10) +#define RCC_MP_APB2LPENCLRR_USART6LPEN BIT(13) +#define RCC_MP_APB2LPENCLRR_SAI1LPEN BIT(16) +#define RCC_MP_APB2LPENCLRR_SAI2LPEN BIT(17) +#define RCC_MP_APB2LPENCLRR_SAI3LPEN BIT(18) +#define RCC_MP_APB2LPENCLRR_DFSDMLPEN BIT(20) +#define RCC_MP_APB2LPENCLRR_ADFSDMLPEN BIT(21) +#define RCC_MP_APB2LPENCLRR_FDCANLPEN BIT(24) + +/* RCC_MP_APB3LPENSETR register fields */ +#define RCC_MP_APB3LPENSETR_LPTIM2LPEN BIT(0) +#define RCC_MP_APB3LPENSETR_LPTIM3LPEN BIT(1) +#define RCC_MP_APB3LPENSETR_LPTIM4LPEN BIT(2) +#define RCC_MP_APB3LPENSETR_LPTIM5LPEN BIT(3) +#define RCC_MP_APB3LPENSETR_SAI4LPEN BIT(8) +#define RCC_MP_APB3LPENSETR_SYSCFGLPEN BIT(11) +#define RCC_MP_APB3LPENSETR_VREFLPEN BIT(13) +#define RCC_MP_APB3LPENSETR_TMPSENSLPEN BIT(16) +#define RCC_MP_APB3LPENSETR_PMBCTRLLPEN BIT(17) + +/* RCC_MP_APB3LPENCLRR register fields */ +#define RCC_MP_APB3LPENCLRR_LPTIM2LPEN BIT(0) +#define RCC_MP_APB3LPENCLRR_LPTIM3LPEN BIT(1) +#define RCC_MP_APB3LPENCLRR_LPTIM4LPEN BIT(2) +#define RCC_MP_APB3LPENCLRR_LPTIM5LPEN BIT(3) +#define RCC_MP_APB3LPENCLRR_SAI4LPEN BIT(8) +#define RCC_MP_APB3LPENCLRR_SYSCFGLPEN BIT(11) +#define RCC_MP_APB3LPENCLRR_VREFLPEN BIT(13) +#define RCC_MP_APB3LPENCLRR_TMPSENSLPEN BIT(16) +#define RCC_MP_APB3LPENCLRR_PMBCTRLLPEN BIT(17) + +/* RCC_MP_AHB2LPENSETR register fields */ +#define RCC_MP_AHB2LPENSETR_DMA1LPEN BIT(0) +#define RCC_MP_AHB2LPENSETR_DMA2LPEN BIT(1) +#define RCC_MP_AHB2LPENSETR_DMAMUXLPEN BIT(2) +#define RCC_MP_AHB2LPENSETR_ADC12LPEN BIT(5) +#define RCC_MP_AHB2LPENSETR_USBOLPEN BIT(8) +#define RCC_MP_AHB2LPENSETR_SDMMC3LPEN BIT(16) + +/* RCC_MP_AHB2LPENCLRR register fields */ +#define RCC_MP_AHB2LPENCLRR_DMA1LPEN BIT(0) +#define RCC_MP_AHB2LPENCLRR_DMA2LPEN BIT(1) +#define RCC_MP_AHB2LPENCLRR_DMAMUXLPEN BIT(2) +#define RCC_MP_AHB2LPENCLRR_ADC12LPEN BIT(5) +#define RCC_MP_AHB2LPENCLRR_USBOLPEN BIT(8) +#define RCC_MP_AHB2LPENCLRR_SDMMC3LPEN BIT(16) + +/* RCC_MP_AHB3LPENSETR register fields */ +#define RCC_MP_AHB3LPENSETR_DCMILPEN BIT(0) +#define RCC_MP_AHB3LPENSETR_CRYP2LPEN BIT(4) +#define RCC_MP_AHB3LPENSETR_HASH2LPEN BIT(5) +#define RCC_MP_AHB3LPENSETR_RNG2LPEN BIT(6) +#define RCC_MP_AHB3LPENSETR_CRC2LPEN BIT(7) +#define RCC_MP_AHB3LPENSETR_HSEMLPEN BIT(11) +#define RCC_MP_AHB3LPENSETR_IPCCLPEN BIT(12) + +/* RCC_MP_AHB3LPENCLRR register fields */ +#define RCC_MP_AHB3LPENCLRR_DCMILPEN BIT(0) +#define RCC_MP_AHB3LPENCLRR_CRYP2LPEN BIT(4) +#define RCC_MP_AHB3LPENCLRR_HASH2LPEN BIT(5) +#define RCC_MP_AHB3LPENCLRR_RNG2LPEN BIT(6) +#define RCC_MP_AHB3LPENCLRR_CRC2LPEN BIT(7) +#define RCC_MP_AHB3LPENCLRR_HSEMLPEN BIT(11) +#define RCC_MP_AHB3LPENCLRR_IPCCLPEN BIT(12) + +/* RCC_MP_AHB4LPENSETR register fields */ +#define RCC_MP_AHB4LPENSETR_GPIOALPEN BIT(0) +#define RCC_MP_AHB4LPENSETR_GPIOBLPEN BIT(1) +#define RCC_MP_AHB4LPENSETR_GPIOCLPEN BIT(2) +#define RCC_MP_AHB4LPENSETR_GPIODLPEN BIT(3) +#define RCC_MP_AHB4LPENSETR_GPIOELPEN BIT(4) +#define RCC_MP_AHB4LPENSETR_GPIOFLPEN BIT(5) +#define RCC_MP_AHB4LPENSETR_GPIOGLPEN BIT(6) +#define RCC_MP_AHB4LPENSETR_GPIOHLPEN BIT(7) +#define RCC_MP_AHB4LPENSETR_GPIOILPEN BIT(8) +#define RCC_MP_AHB4LPENSETR_GPIOJLPEN BIT(9) +#define RCC_MP_AHB4LPENSETR_GPIOKLPEN BIT(10) + +/* RCC_MP_AHB4LPENCLRR register fields */ +#define RCC_MP_AHB4LPENCLRR_GPIOALPEN BIT(0) +#define RCC_MP_AHB4LPENCLRR_GPIOBLPEN BIT(1) +#define RCC_MP_AHB4LPENCLRR_GPIOCLPEN BIT(2) +#define RCC_MP_AHB4LPENCLRR_GPIODLPEN BIT(3) +#define RCC_MP_AHB4LPENCLRR_GPIOELPEN BIT(4) +#define RCC_MP_AHB4LPENCLRR_GPIOFLPEN BIT(5) +#define RCC_MP_AHB4LPENCLRR_GPIOGLPEN BIT(6) +#define RCC_MP_AHB4LPENCLRR_GPIOHLPEN BIT(7) +#define RCC_MP_AHB4LPENCLRR_GPIOILPEN BIT(8) +#define RCC_MP_AHB4LPENCLRR_GPIOJLPEN BIT(9) +#define RCC_MP_AHB4LPENCLRR_GPIOKLPEN BIT(10) + +/* RCC_MP_AXIMLPENSETR register fields */ +#define RCC_MP_AXIMLPENSETR_SYSRAMLPEN BIT(0) + +/* RCC_MP_AXIMLPENCLRR register fields */ +#define RCC_MP_AXIMLPENCLRR_SYSRAMLPEN BIT(0) + +/* RCC_MP_MLAHBLPENSETR register fields */ +#define RCC_MP_MLAHBLPENSETR_SRAM1LPEN BIT(0) +#define RCC_MP_MLAHBLPENSETR_SRAM2LPEN BIT(1) +#define RCC_MP_MLAHBLPENSETR_SRAM34LPEN BIT(2) +#define RCC_MP_MLAHBLPENSETR_RETRAMLPEN BIT(4) + +/* RCC_MP_MLAHBLPENCLRR register fields */ +#define RCC_MP_MLAHBLPENCLRR_SRAM1LPEN BIT(0) +#define RCC_MP_MLAHBLPENCLRR_SRAM2LPEN BIT(1) +#define RCC_MP_MLAHBLPENCLRR_SRAM34LPEN BIT(2) +#define RCC_MP_MLAHBLPENCLRR_RETRAMLPEN BIT(4) + +/* RCC_MC_APB1LPENSETR register fields */ +#define RCC_MC_APB1LPENSETR_TIM2LPEN BIT(0) +#define RCC_MC_APB1LPENSETR_TIM3LPEN BIT(1) +#define RCC_MC_APB1LPENSETR_TIM4LPEN BIT(2) +#define RCC_MC_APB1LPENSETR_TIM5LPEN BIT(3) +#define RCC_MC_APB1LPENSETR_TIM6LPEN BIT(4) +#define RCC_MC_APB1LPENSETR_TIM7LPEN BIT(5) +#define RCC_MC_APB1LPENSETR_TIM12LPEN BIT(6) +#define RCC_MC_APB1LPENSETR_TIM13LPEN BIT(7) +#define RCC_MC_APB1LPENSETR_TIM14LPEN BIT(8) +#define RCC_MC_APB1LPENSETR_LPTIM1LPEN BIT(9) +#define RCC_MC_APB1LPENSETR_SPI2LPEN BIT(11) +#define RCC_MC_APB1LPENSETR_SPI3LPEN BIT(12) +#define RCC_MC_APB1LPENSETR_USART2LPEN BIT(14) +#define RCC_MC_APB1LPENSETR_USART3LPEN BIT(15) +#define RCC_MC_APB1LPENSETR_UART4LPEN BIT(16) +#define RCC_MC_APB1LPENSETR_UART5LPEN BIT(17) +#define RCC_MC_APB1LPENSETR_UART7LPEN BIT(18) +#define RCC_MC_APB1LPENSETR_UART8LPEN BIT(19) +#define RCC_MC_APB1LPENSETR_I2C1LPEN BIT(21) +#define RCC_MC_APB1LPENSETR_I2C2LPEN BIT(22) +#define RCC_MC_APB1LPENSETR_I2C3LPEN BIT(23) +#define RCC_MC_APB1LPENSETR_I2C5LPEN BIT(24) +#define RCC_MC_APB1LPENSETR_SPDIFLPEN BIT(26) +#define RCC_MC_APB1LPENSETR_CECLPEN BIT(27) +#define RCC_MC_APB1LPENSETR_WWDG1LPEN BIT(28) +#define RCC_MC_APB1LPENSETR_DAC12LPEN BIT(29) +#define RCC_MC_APB1LPENSETR_MDIOSLPEN BIT(31) + +/* RCC_MC_APB1LPENCLRR register fields */ +#define RCC_MC_APB1LPENCLRR_TIM2LPEN BIT(0) +#define RCC_MC_APB1LPENCLRR_TIM3LPEN BIT(1) +#define RCC_MC_APB1LPENCLRR_TIM4LPEN BIT(2) +#define RCC_MC_APB1LPENCLRR_TIM5LPEN BIT(3) +#define RCC_MC_APB1LPENCLRR_TIM6LPEN BIT(4) +#define RCC_MC_APB1LPENCLRR_TIM7LPEN BIT(5) +#define RCC_MC_APB1LPENCLRR_TIM12LPEN BIT(6) +#define RCC_MC_APB1LPENCLRR_TIM13LPEN BIT(7) +#define RCC_MC_APB1LPENCLRR_TIM14LPEN BIT(8) +#define RCC_MC_APB1LPENCLRR_LPTIM1LPEN BIT(9) +#define RCC_MC_APB1LPENCLRR_SPI2LPEN BIT(11) +#define RCC_MC_APB1LPENCLRR_SPI3LPEN BIT(12) +#define RCC_MC_APB1LPENCLRR_USART2LPEN BIT(14) +#define RCC_MC_APB1LPENCLRR_USART3LPEN BIT(15) +#define RCC_MC_APB1LPENCLRR_UART4LPEN BIT(16) +#define RCC_MC_APB1LPENCLRR_UART5LPEN BIT(17) +#define RCC_MC_APB1LPENCLRR_UART7LPEN BIT(18) +#define RCC_MC_APB1LPENCLRR_UART8LPEN BIT(19) +#define RCC_MC_APB1LPENCLRR_I2C1LPEN BIT(21) +#define RCC_MC_APB1LPENCLRR_I2C2LPEN BIT(22) +#define RCC_MC_APB1LPENCLRR_I2C3LPEN BIT(23) +#define RCC_MC_APB1LPENCLRR_I2C5LPEN BIT(24) +#define RCC_MC_APB1LPENCLRR_SPDIFLPEN BIT(26) +#define RCC_MC_APB1LPENCLRR_CECLPEN BIT(27) +#define RCC_MC_APB1LPENCLRR_WWDG1LPEN BIT(28) +#define RCC_MC_APB1LPENCLRR_DAC12LPEN BIT(29) +#define RCC_MC_APB1LPENCLRR_MDIOSLPEN BIT(31) + +/* RCC_MC_APB2LPENSETR register fields */ +#define RCC_MC_APB2LPENSETR_TIM1LPEN BIT(0) +#define RCC_MC_APB2LPENSETR_TIM8LPEN BIT(1) +#define RCC_MC_APB2LPENSETR_TIM15LPEN BIT(2) +#define RCC_MC_APB2LPENSETR_TIM16LPEN BIT(3) +#define RCC_MC_APB2LPENSETR_TIM17LPEN BIT(4) +#define RCC_MC_APB2LPENSETR_SPI1LPEN BIT(8) +#define RCC_MC_APB2LPENSETR_SPI4LPEN BIT(9) +#define RCC_MC_APB2LPENSETR_SPI5LPEN BIT(10) +#define RCC_MC_APB2LPENSETR_USART6LPEN BIT(13) +#define RCC_MC_APB2LPENSETR_SAI1LPEN BIT(16) +#define RCC_MC_APB2LPENSETR_SAI2LPEN BIT(17) +#define RCC_MC_APB2LPENSETR_SAI3LPEN BIT(18) +#define RCC_MC_APB2LPENSETR_DFSDMLPEN BIT(20) +#define RCC_MC_APB2LPENSETR_ADFSDMLPEN BIT(21) +#define RCC_MC_APB2LPENSETR_FDCANLPEN BIT(24) + +/* RCC_MC_APB2LPENCLRR register fields */ +#define RCC_MC_APB2LPENCLRR_TIM1LPEN BIT(0) +#define RCC_MC_APB2LPENCLRR_TIM8LPEN BIT(1) +#define RCC_MC_APB2LPENCLRR_TIM15LPEN BIT(2) +#define RCC_MC_APB2LPENCLRR_TIM16LPEN BIT(3) +#define RCC_MC_APB2LPENCLRR_TIM17LPEN BIT(4) +#define RCC_MC_APB2LPENCLRR_SPI1LPEN BIT(8) +#define RCC_MC_APB2LPENCLRR_SPI4LPEN BIT(9) +#define RCC_MC_APB2LPENCLRR_SPI5LPEN BIT(10) +#define RCC_MC_APB2LPENCLRR_USART6LPEN BIT(13) +#define RCC_MC_APB2LPENCLRR_SAI1LPEN BIT(16) +#define RCC_MC_APB2LPENCLRR_SAI2LPEN BIT(17) +#define RCC_MC_APB2LPENCLRR_SAI3LPEN BIT(18) +#define RCC_MC_APB2LPENCLRR_DFSDMLPEN BIT(20) +#define RCC_MC_APB2LPENCLRR_ADFSDMLPEN BIT(21) +#define RCC_MC_APB2LPENCLRR_FDCANLPEN BIT(24) + +/* RCC_MC_APB3LPENSETR register fields */ +#define RCC_MC_APB3LPENSETR_LPTIM2LPEN BIT(0) +#define RCC_MC_APB3LPENSETR_LPTIM3LPEN BIT(1) +#define RCC_MC_APB3LPENSETR_LPTIM4LPEN BIT(2) +#define RCC_MC_APB3LPENSETR_LPTIM5LPEN BIT(3) +#define RCC_MC_APB3LPENSETR_SAI4LPEN BIT(8) +#define RCC_MC_APB3LPENSETR_SYSCFGLPEN BIT(11) +#define RCC_MC_APB3LPENSETR_VREFLPEN BIT(13) +#define RCC_MC_APB3LPENSETR_TMPSENSLPEN BIT(16) +#define RCC_MC_APB3LPENSETR_PMBCTRLLPEN BIT(17) + +/* RCC_MC_APB3LPENCLRR register fields */ +#define RCC_MC_APB3LPENCLRR_LPTIM2LPEN BIT(0) +#define RCC_MC_APB3LPENCLRR_LPTIM3LPEN BIT(1) +#define RCC_MC_APB3LPENCLRR_LPTIM4LPEN BIT(2) +#define RCC_MC_APB3LPENCLRR_LPTIM5LPEN BIT(3) +#define RCC_MC_APB3LPENCLRR_SAI4LPEN BIT(8) +#define RCC_MC_APB3LPENCLRR_SYSCFGLPEN BIT(11) +#define RCC_MC_APB3LPENCLRR_VREFLPEN BIT(13) +#define RCC_MC_APB3LPENCLRR_TMPSENSLPEN BIT(16) +#define RCC_MC_APB3LPENCLRR_PMBCTRLLPEN BIT(17) + +/* RCC_MC_AHB2LPENSETR register fields */ +#define RCC_MC_AHB2LPENSETR_DMA1LPEN BIT(0) +#define RCC_MC_AHB2LPENSETR_DMA2LPEN BIT(1) +#define RCC_MC_AHB2LPENSETR_DMAMUXLPEN BIT(2) +#define RCC_MC_AHB2LPENSETR_ADC12LPEN BIT(5) +#define RCC_MC_AHB2LPENSETR_USBOLPEN BIT(8) +#define RCC_MC_AHB2LPENSETR_SDMMC3LPEN BIT(16) + +/* RCC_MC_AHB2LPENCLRR register fields */ +#define RCC_MC_AHB2LPENCLRR_DMA1LPEN BIT(0) +#define RCC_MC_AHB2LPENCLRR_DMA2LPEN BIT(1) +#define RCC_MC_AHB2LPENCLRR_DMAMUXLPEN BIT(2) +#define RCC_MC_AHB2LPENCLRR_ADC12LPEN BIT(5) +#define RCC_MC_AHB2LPENCLRR_USBOLPEN BIT(8) +#define RCC_MC_AHB2LPENCLRR_SDMMC3LPEN BIT(16) + +/* RCC_MC_AHB3LPENSETR register fields */ +#define RCC_MC_AHB3LPENSETR_DCMILPEN BIT(0) +#define RCC_MC_AHB3LPENSETR_CRYP2LPEN BIT(4) +#define RCC_MC_AHB3LPENSETR_HASH2LPEN BIT(5) +#define RCC_MC_AHB3LPENSETR_RNG2LPEN BIT(6) +#define RCC_MC_AHB3LPENSETR_CRC2LPEN BIT(7) +#define RCC_MC_AHB3LPENSETR_HSEMLPEN BIT(11) +#define RCC_MC_AHB3LPENSETR_IPCCLPEN BIT(12) + +/* RCC_MC_AHB3LPENCLRR register fields */ +#define RCC_MC_AHB3LPENCLRR_DCMILPEN BIT(0) +#define RCC_MC_AHB3LPENCLRR_CRYP2LPEN BIT(4) +#define RCC_MC_AHB3LPENCLRR_HASH2LPEN BIT(5) +#define RCC_MC_AHB3LPENCLRR_RNG2LPEN BIT(6) +#define RCC_MC_AHB3LPENCLRR_CRC2LPEN BIT(7) +#define RCC_MC_AHB3LPENCLRR_HSEMLPEN BIT(11) +#define RCC_MC_AHB3LPENCLRR_IPCCLPEN BIT(12) + +/* RCC_MC_AHB4LPENSETR register fields */ +#define RCC_MC_AHB4LPENSETR_GPIOALPEN BIT(0) +#define RCC_MC_AHB4LPENSETR_GPIOBLPEN BIT(1) +#define RCC_MC_AHB4LPENSETR_GPIOCLPEN BIT(2) +#define RCC_MC_AHB4LPENSETR_GPIODLPEN BIT(3) +#define RCC_MC_AHB4LPENSETR_GPIOELPEN BIT(4) +#define RCC_MC_AHB4LPENSETR_GPIOFLPEN BIT(5) +#define RCC_MC_AHB4LPENSETR_GPIOGLPEN BIT(6) +#define RCC_MC_AHB4LPENSETR_GPIOHLPEN BIT(7) +#define RCC_MC_AHB4LPENSETR_GPIOILPEN BIT(8) +#define RCC_MC_AHB4LPENSETR_GPIOJLPEN BIT(9) +#define RCC_MC_AHB4LPENSETR_GPIOKLPEN BIT(10) + +/* RCC_MC_AHB4LPENCLRR register fields */ +#define RCC_MC_AHB4LPENCLRR_GPIOALPEN BIT(0) +#define RCC_MC_AHB4LPENCLRR_GPIOBLPEN BIT(1) +#define RCC_MC_AHB4LPENCLRR_GPIOCLPEN BIT(2) +#define RCC_MC_AHB4LPENCLRR_GPIODLPEN BIT(3) +#define RCC_MC_AHB4LPENCLRR_GPIOELPEN BIT(4) +#define RCC_MC_AHB4LPENCLRR_GPIOFLPEN BIT(5) +#define RCC_MC_AHB4LPENCLRR_GPIOGLPEN BIT(6) +#define RCC_MC_AHB4LPENCLRR_GPIOHLPEN BIT(7) +#define RCC_MC_AHB4LPENCLRR_GPIOILPEN BIT(8) +#define RCC_MC_AHB4LPENCLRR_GPIOJLPEN BIT(9) +#define RCC_MC_AHB4LPENCLRR_GPIOKLPEN BIT(10) + +/* RCC_MC_AXIMLPENSETR register fields */ +#define RCC_MC_AXIMLPENSETR_SYSRAMLPEN BIT(0) + +/* RCC_MC_AXIMLPENCLRR register fields */ +#define RCC_MC_AXIMLPENCLRR_SYSRAMLPEN BIT(0) + +/* RCC_MC_MLAHBLPENSETR register fields */ +#define RCC_MC_MLAHBLPENSETR_SRAM1LPEN BIT(0) +#define RCC_MC_MLAHBLPENSETR_SRAM2LPEN BIT(1) +#define RCC_MC_MLAHBLPENSETR_SRAM34LPEN BIT(2) +#define RCC_MC_MLAHBLPENSETR_RETRAMLPEN BIT(4) + +/* RCC_MC_MLAHBLPENCLRR register fields */ +#define RCC_MC_MLAHBLPENCLRR_SRAM1LPEN BIT(0) +#define RCC_MC_MLAHBLPENCLRR_SRAM2LPEN BIT(1) +#define RCC_MC_MLAHBLPENCLRR_SRAM34LPEN BIT(2) +#define RCC_MC_MLAHBLPENCLRR_RETRAMLPEN BIT(4) + +/* RCC_MC_RSTSCLRR register fields */ +#define RCC_MC_RSTSCLRR_PORRSTF BIT(0) +#define RCC_MC_RSTSCLRR_BORRSTF BIT(1) +#define RCC_MC_RSTSCLRR_PADRSTF BIT(2) +#define RCC_MC_RSTSCLRR_HCSSRSTF BIT(3) +#define RCC_MC_RSTSCLRR_VCORERSTF BIT(4) +#define RCC_MC_RSTSCLRR_MCURSTF BIT(5) +#define RCC_MC_RSTSCLRR_MPSYSRSTF BIT(6) +#define RCC_MC_RSTSCLRR_MCSYSRSTF BIT(7) +#define RCC_MC_RSTSCLRR_IWDG1RSTF BIT(8) +#define RCC_MC_RSTSCLRR_IWDG2RSTF BIT(9) +#define RCC_MC_RSTSCLRR_WWDG1RSTF BIT(10) + +/* RCC_MC_CIER register fields */ +#define RCC_MC_CIER_LSIRDYIE BIT(0) +#define RCC_MC_CIER_LSERDYIE BIT(1) +#define RCC_MC_CIER_HSIRDYIE BIT(2) +#define RCC_MC_CIER_HSERDYIE BIT(3) +#define RCC_MC_CIER_CSIRDYIE BIT(4) +#define RCC_MC_CIER_PLL1DYIE BIT(8) +#define RCC_MC_CIER_PLL2DYIE BIT(9) +#define RCC_MC_CIER_PLL3DYIE BIT(10) +#define RCC_MC_CIER_PLL4DYIE BIT(11) +#define RCC_MC_CIER_LSECSSIE BIT(16) +#define RCC_MC_CIER_WKUPIE BIT(20) + +/* RCC_MC_CIFR register fields */ +#define RCC_MC_CIFR_LSIRDYF BIT(0) +#define RCC_MC_CIFR_LSERDYF BIT(1) +#define RCC_MC_CIFR_HSIRDYF BIT(2) +#define RCC_MC_CIFR_HSERDYF BIT(3) +#define RCC_MC_CIFR_CSIRDYF BIT(4) +#define RCC_MC_CIFR_PLL1DYF BIT(8) +#define RCC_MC_CIFR_PLL2DYF BIT(9) +#define RCC_MC_CIFR_PLL3DYF BIT(10) +#define RCC_MC_CIFR_PLL4DYF BIT(11) +#define RCC_MC_CIFR_LSECSSF BIT(16) +#define RCC_MC_CIFR_WKUPF BIT(20) + +/* RCC_VERR register fields */ +#define RCC_VERR_MINREV_MASK GENMASK(3, 0) +#define RCC_VERR_MINREV_SHIFT 0 +#define RCC_VERR_MAJREV_MASK GENMASK(7, 4) +#define RCC_VERR_MAJREV_SHIFT 4 + +/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */ +#define RCC_OCENR_HSION BIT(0) +#define RCC_OCENR_HSIKERON BIT(1) +#define RCC_OCENR_CSION BIT(4) +#define RCC_OCENR_CSIKERON BIT(5) +#define RCC_OCENR_DIGBYP BIT(7) +#define RCC_OCENR_HSEON BIT(8) +#define RCC_OCENR_HSEKERON BIT(9) +#define RCC_OCENR_HSEBYP BIT(10) +#define RCC_OCENR_HSECSSON BIT(11) + +/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */ +#define RCC_MP_ENCLRR_OFFSET U(4) + +/* Offset between RCC_xxxRSTSETR and RCC_xxxRSTCLRR registers */ +#define RCC_RSTCLRR_OFFSET U(4) + +/* Used for most of DIVR register: max div for RTC */ +#define RCC_DIVR_DIV_MASK GENMASK(5, 0) +#define RCC_DIVR_DIVRDY BIT(31) + +/* Masks for specific DIVR registers */ +#define RCC_APBXDIV_MASK GENMASK(2, 0) +#define RCC_MPUDIV_MASK GENMASK(2, 0) +#define RCC_AXIDIV_MASK GENMASK(2, 0) +#define RCC_MCUDIV_MASK GENMASK(3, 0) + +/* Used for most of RCC_SELR registers */ +#define RCC_SELR_SRC_MASK GENMASK(2, 0) +#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0) +#define RCC_SELR_SRCRDY BIT(31) + +/* Used for all RCC_PLLCR registers */ +#define RCC_PLLNCR_PLLON BIT(0) +#define RCC_PLLNCR_PLLRDY BIT(1) +#define RCC_PLLNCR_SSCG_CTRL BIT(2) +#define RCC_PLLNCR_DIVPEN BIT(4) +#define RCC_PLLNCR_DIVQEN BIT(5) +#define RCC_PLLNCR_DIVREN BIT(6) +#define RCC_PLLNCR_DIVEN_SHIFT 4 + +/* Used for all RCC_PLLCFGR1 registers */ +#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16) +#define RCC_PLLNCFGR1_DIVM_SHIFT 16 +#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0) +#define RCC_PLLNCFGR1_DIVN_SHIFT 0 + +/* Only for PLL3 and PLL4 */ +#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24) +#define RCC_PLLNCFGR1_IFRGE_SHIFT 24 + +/* Used for all RCC_PLLCFGR2 registers */ +#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0) +#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0) +#define RCC_PLLNCFGR2_DIVP_SHIFT 0 +#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8) +#define RCC_PLLNCFGR2_DIVQ_SHIFT 8 +#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16) +#define RCC_PLLNCFGR2_DIVR_SHIFT 16 + +/* Used for all RCC_PLLFRACR registers */ +#define RCC_PLLNFRACR_FRACV_SHIFT 3 +#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3) +#define RCC_PLLNFRACR_FRACLE BIT(16) + +/* Used for all RCC_PLLCSGR registers */ +#define RCC_PLLNCSGR_INC_STEP_SHIFT 16 +#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16) +#define RCC_PLLNCSGR_MOD_PER_SHIFT 0 +#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0) +#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15 +#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15) + +/* Used for TIMER Prescaler */ +#define RCC_TIMGXPRER_TIMGXPRE BIT(0) + +/* Used for RCC_MCO related operations */ +#define RCC_MCOCFG_MCOON BIT(12) +#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4) +#define RCC_MCOCFG_MCODIV_SHIFT 4 +#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0) + #endif /* STM32MP1_RCC_H */ -- cgit v1.2.3 From b38e2ed29ef791dad0cb61fed81b74d612f58b01 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 14 Sep 2020 17:21:59 +0200 Subject: fix(plat/st): add UART reset in crash console init Add the reset set/clear sequence at the beginning of the function plat_crash_console_init(). If not done, there is a risk that the UART is in a bad state and will not be able to print correct characters. Change-Id: Id31e28773d6c4f26f16d3569d1e3c5aa0e26e039 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_def.h | 2 ++ plat/st/stm32mp1/stm32mp1_helper.S | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 0d3666074..469c2d93b 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -205,6 +205,8 @@ enum ddr_type { #define DEBUG_UART_TX_CLKSRC RCC_UART24CKSELR_HSI #define DEBUG_UART_TX_EN_REG RCC_MP_APB1ENSETR #define DEBUG_UART_TX_EN RCC_MP_APB1ENSETR_UART4EN +#define DEBUG_UART_RST_REG RCC_APB1RSTSETR +#define DEBUG_UART_RST_BIT RCC_APB1RSTSETR_UART4RST /******************************************************************************* * STM32MP1 ETZPC diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S index 84e9e8d43..cac9752e2 100644 --- a/plat/st/stm32mp1/stm32mp1_helper.S +++ b/plat/st/stm32mp1/stm32mp1_helper.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -148,6 +148,19 @@ endfunc plat_my_core_pos * --------------------------------------------- */ func plat_crash_console_init + /* Reset UART peripheral */ + ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG) + ldr r2, =DEBUG_UART_RST_BIT + str r2, [r1] +1: + ldr r0, [r1] + ands r2, r0, r2 + beq 1b + str r2, [r1, #4] /* RSTCLR register */ +2: + ldr r0, [r1] + ands r2, r0, r2 + bne 2b /* Enable GPIOs for UART TX */ ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG) ldr r2, [r1] -- cgit v1.2.3 From 49c7f0cef4cc864185828750f1f61f3f33f284f7 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 9 Sep 2021 17:34:53 +0200 Subject: fix(stm32_console): do not skip init for crash console In BL32, only skip UART initialization if UART enable bit is set. Due to patch [1], a reset of UART is done in crash console init. In this case, UART should then be reconfigured. [1] 7fa2e96e1 ("stm32mp1: add UART reset in crash console init") Signed-off-by: Yann Gautier Change-Id: I650d4c387b60dd74b780e6f3adfd629ea44f5834 --- drivers/st/uart/aarch32/stm32_console.S | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S index 686b18b96..2b8879a11 100644 --- a/drivers/st/uart/aarch32/stm32_console.S +++ b/drivers/st/uart/aarch32/stm32_console.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,7 +45,12 @@ func console_stm32_core_init /* Check the input base address */ cmp r0, #0 beq core_init_fail -#if defined(IMAGE_BL2) +#if !defined(IMAGE_BL2) + /* Skip UART initialization if it is already enabled */ + ldr r3, [r0, #USART_CR1] + ands r3, r3, #USART_CR1_UE + bne 1f +#endif /* IMAGE_BL2 */ /* Check baud rate and uart clock for sanity */ cmp r1, #0 beq core_init_fail @@ -78,7 +83,7 @@ teack_loop: ldr r3, [r0, #USART_ISR] tst r3, #USART_ISR_TEACK beq teack_loop -#endif /* IMAGE_BL2 */ +1: mov r0, #1 bx lr core_init_fail: -- cgit v1.2.3 From 46ee50e0b34e19d383a28bc3b3dadbfb4c07b270 Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Mon, 24 May 2021 17:35:34 +0530 Subject: feat(plat/qti/sc7280): support for qti sc7280 plat new qti platform sc7280 support addition Signed-off-by: Saurabh Gorecha Change-Id: I3dd99d8744a6c313f7dfbbee7ae2cbd6f21656c1 --- docs/plat/qti.rst | 8 +- plat/qti/common/inc/qti_cpu.h | 8 +- plat/qti/common/src/aarch64/qti_kryo6_gold.S | 83 +++++++++ plat/qti/common/src/aarch64/qti_kryo6_silver.S | 79 +++++++++ plat/qti/common/src/qti_gic_v3.c | 12 +- plat/qti/qtiseclib/inc/qtiseclib_interface.h | 18 +- .../qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h | 45 +++++ plat/qti/qtiseclib/src/qtiseclib_cb_interface.c | 4 + plat/qti/sc7280/inc/platform_def.h | 194 +++++++++++++++++++++ plat/qti/sc7280/inc/qti_rng_io.h | 15 ++ plat/qti/sc7280/inc/qti_secure_io_cfg.h | 30 ++++ plat/qti/sc7280/platform.mk | 119 +++++++++++++ 12 files changed, 609 insertions(+), 6 deletions(-) create mode 100644 plat/qti/common/src/aarch64/qti_kryo6_gold.S create mode 100644 plat/qti/common/src/aarch64/qti_kryo6_silver.S create mode 100644 plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h create mode 100644 plat/qti/sc7280/inc/platform_def.h create mode 100644 plat/qti/sc7280/inc/qti_rng_io.h create mode 100644 plat/qti/sc7280/inc/qti_secure_io_cfg.h create mode 100644 plat/qti/sc7280/platform.mk diff --git a/docs/plat/qti.rst b/docs/plat/qti.rst index 814e6726a..1d483e76f 100644 --- a/docs/plat/qti.rst +++ b/docs/plat/qti.rst @@ -1,8 +1,8 @@ Qualcomm Technologies, Inc. =========================== -Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180. - +Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QTI SC7180, +SC7280. Boot Trace ------------- @@ -38,4 +38,6 @@ is picked. qtiseclib with stub implementation doesn't boot device. This was added to satisfy compilation. QTISELIB for SC7180 is available at -`link `__ +`link `__ +QTISELIB for SC7280 is available at +`link `__ diff --git a/plat/qti/common/inc/qti_cpu.h b/plat/qti/common/inc/qti_cpu.h index 3eda02bbb..3316f7bb2 100644 --- a/plat/qti/common/inc/qti_cpu.h +++ b/plat/qti/common/inc/qti_cpu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,4 +13,10 @@ /* KRYO-4xx Silver MIDR */ #define QTI_KRYO4_SILVER_MIDR 0x517F805D +/* KRYO-6xx Gold MIDR */ +#define QTI_KRYO6_GOLD_MIDR 0x412FD410 + +/* KRYO-6xx Silver MIDR */ +#define QTI_KRYO6_SILVER_MIDR 0x412FD050 + #endif /* QTI_CPU_H */ diff --git a/plat/qti/common/src/aarch64/qti_kryo6_gold.S b/plat/qti/common/src/aarch64/qti_kryo6_gold.S new file mode 100644 index 000000000..db1a304ea --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_kryo6_gold.S @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + + .p2align 3 + +/* ------------------------------------------------- + * The CPU Ops reset function for Kryo-3 Gold + * ------------------------------------------------- + */ +func qti_kryo6_gold_reset_func +#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715 + adr x0, wa_cve_2017_5715_bpiall_vbar + msr vbar_el3, x0 + isb +#endif + + mov x19, x30 + + bl qtiseclib_kryo6_gold_reset_asm + + ret x19 + +endfunc qti_kryo6_gold_reset_func + +/* ---------------------------------------------------- + * The CPU Ops core power down function for Kryo-3 Gold + * ---------------------------------------------------- + */ +func qti_kryo6_gold_core_pwr_dwn + ret +endfunc qti_kryo6_gold_core_pwr_dwn + +/* ------------------------------------------------------- + * The CPU Ops cluster power down function for Kryo-3 Gold + * ------------------------------------------------------- + */ +func qti_kryo6_gold_cluster_pwr_dwn + ret +endfunc qti_kryo6_gold_cluster_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Kryo4 Gold. Must follow AAPCS. + */ +func qti_kryo6_gold_errata_report + /* TODO : Need to add support. Required only for debug bl31 image.*/ + ret +endfunc qti_kryo6_gold_errata_report +#endif + +/* --------------------------------------------- + * This function provides kryo4_gold specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ASCII and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.qti_kryo4_gold_regs, "aS" +qti_kryo6_gold_regs: /* The ASCII list of register names to be reported */ + .asciz "" + +func qti_kryo6_gold_cpu_reg_dump + adr x6, qti_kryo6_gold_regs + ret +endfunc qti_kryo6_gold_cpu_reg_dump + +declare_cpu_ops qti_kryo6_gold, QTI_KRYO6_GOLD_MIDR, \ + qti_kryo6_gold_reset_func, \ + qti_kryo6_gold_core_pwr_dwn, \ + qti_kryo6_gold_cluster_pwr_dwn diff --git a/plat/qti/common/src/aarch64/qti_kryo6_silver.S b/plat/qti/common/src/aarch64/qti_kryo6_silver.S new file mode 100644 index 000000000..2d189f233 --- /dev/null +++ b/plat/qti/common/src/aarch64/qti_kryo6_silver.S @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include + + .p2align 3 + +/* ------------------------------------------------- + * The CPU Ops reset function for Kryo-3 Silver + * ------------------------------------------------- + */ +func qti_kryo6_silver_reset_func + mov x19, x30 + + bl qtiseclib_kryo6_silver_reset_asm + + ret x19 + +endfunc qti_kryo6_silver_reset_func + +/* ------------------------------------------------------ + * The CPU Ops core power down function for Kryo-3 Silver + * ------------------------------------------------------ + */ +func qti_kryo6_silver_core_pwr_dwn + ret +endfunc qti_kryo6_silver_core_pwr_dwn + +/* --------------------------------------------------------- + * The CPU Ops cluster power down function for Kryo-3 Silver + * --------------------------------------------------------- + */ +func qti_kryo6_silver_cluster_pwr_dwn + ret +endfunc qti_kryo6_silver_cluster_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Kryo4 Silver. Must follow AAPCS. + */ +func qti_kryo6_silver_errata_report + /* TODO : Need to add support. Required only for debug bl31 image.*/ + ret +endfunc qti_kryo6_silver_errata_report +#endif + + +/* --------------------------------------------- + * This function provides kryo4_silver specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ASCII and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.qti_kryo4_silver_regs, "aS" +qti_kryo6_silver_regs: /* The ASCII list of register names to be reported */ + .asciz "" + +func qti_kryo6_silver_cpu_reg_dump + adr x6, qti_kryo6_silver_regs + ret +endfunc qti_kryo6_silver_cpu_reg_dump + + +declare_cpu_ops qti_kryo6_silver, QTI_KRYO6_SILVER_MIDR, \ + qti_kryo6_silver_reset_func, \ + qti_kryo6_silver_core_pwr_dwn, \ + qti_kryo6_silver_cluster_pwr_dwn diff --git a/plat/qti/common/src/qti_gic_v3.c b/plat/qti/common/src/qti_gic_v3.c index a5e0ae7b0..f00267acd 100644 --- a/plat/qti/common/src/qti_gic_v3.c +++ b/plat/qti/common/src/qti_gic_v3.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -72,6 +72,16 @@ static const interrupt_prop_t qti_interrupt_props[] = { INTR_PROP_DESC(QTISECLIB_INT_ID_MMSS_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, GIC_INTR_CFG_EDGE), +#ifdef QTISECLIB_INT_ID_LPASS_AGNOC_ERROR + INTR_PROP_DESC(QTISECLIB_INT_ID_LPASS_AGNOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), +#endif +#ifdef QTISECLIB_INT_ID_NSP_NOC_ERROR + INTR_PROP_DESC(QTISECLIB_INT_ID_NSP_NOC_ERROR, GIC_HIGHEST_SEC_PRIORITY, + INTR_GROUP0, + GIC_INTR_CFG_EDGE), +#endif }; const gicv3_driver_data_t qti_gic_data = { diff --git a/plat/qti/qtiseclib/inc/qtiseclib_interface.h b/plat/qti/qtiseclib/inc/qtiseclib_interface.h index 315bd6bc7..babed1b61 100644 --- a/plat/qti/qtiseclib/inc/qtiseclib_interface.h +++ b/plat/qti/qtiseclib/inc/qtiseclib_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,6 +49,14 @@ void qtiseclib_cpuss_reset_asm(uint32_t bl31_cold_boot_state); */ void qtiseclib_kryo4_gold_reset_asm(void); +/* + * Execute CPU (Kryo46 gold) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo6_gold_reset_asm(void); + /* * Execute CPU (Kryo4 silver) specific reset handler / system initialization. * This takes care of executing required CPU errata's. @@ -57,6 +65,14 @@ void qtiseclib_kryo4_gold_reset_asm(void); */ void qtiseclib_kryo4_silver_reset_asm(void); +/* + * Execute CPU (Kryo6 silver) specific reset handler / system initialization. + * This takes care of executing required CPU errata's. + * + * Clobbers: x0 - x16 + */ +void qtiseclib_kryo6_silver_reset_asm(void); + /* * C Api's */ diff --git a/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h b/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h new file mode 100644 index 000000000..b3d309f4c --- /dev/null +++ b/plat/qti/qtiseclib/inc/sc7280/qtiseclib_defs_plat.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __QTISECLIB_DEFS_PLAT_H__ +#define __QTISECLIB_DEFS_PLAT_H__ + +#define QTISECLIB_PLAT_CLUSTER_COUNT 1 +#define QTISECLIB_PLAT_CORE_COUNT 8 + +#define BL31_BASE 0xC0000000 +#define BL31_SIZE 0x00100000 + +/*----------------------------------------------------------------------------*/ +/* AOP CMD DB address space for mapping */ +/*----------------------------------------------------------------------------*/ +#define QTI_AOP_CMD_DB_BASE 0x80860000 +#define QTI_AOP_CMD_DB_SIZE 0x00020000 + +/* Chipset specific secure interrupt number/ID defs. */ +#define QTISECLIB_INT_ID_SEC_WDOG_BARK (0x204) +#define QTISECLIB_INT_ID_NON_SEC_WDOG_BITE (0x21) + +#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_SEC (0xE6) +#define QTISECLIB_INT_ID_VMIDMT_ERR_CLT_NONSEC (0xE7) +#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_SEC (0xE8) +#define QTISECLIB_INT_ID_VMIDMT_ERR_CFG_NONSEC (0xE9) + +#define QTISECLIB_INT_ID_XPU_SEC (0xE3) +#define QTISECLIB_INT_ID_XPU_NON_SEC (0xE4) + +//NOC INterrupt +#define QTISECLIB_INT_ID_A1_NOC_ERROR (0xC9) +#define QTISECLIB_INT_ID_A2_NOC_ERROR (0xEA) +#define QTISECLIB_INT_ID_CONFIG_NOC_ERROR (0xE2) +#define QTISECLIB_INT_ID_DC_NOC_ERROR (0x122) +#define QTISECLIB_INT_ID_MEM_NOC_ERROR (0x6C) +#define QTISECLIB_INT_ID_SYSTEM_NOC_ERROR (0xC8) +#define QTISECLIB_INT_ID_MMSS_NOC_ERROR (0xBA) +#define QTISECLIB_INT_ID_LPASS_AGNOC_ERROR (0x143) +#define QTISECLIB_INT_ID_NSP_NOC_ERROR (0x1CE) + +#endif /* __QTISECLIB_DEFS_PLAT_H__ */ diff --git a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c index bb552c66b..c4cd25973 100644 --- a/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c +++ b/plat/qti/qtiseclib/src/qtiseclib_cb_interface.c @@ -132,6 +132,10 @@ void qtiseclib_cb_get_ns_ctx(qtiseclib_dbg_a64_ctxt_regs_type *qti_ns_ctx) void *ctx; ctx = cm_get_context(NON_SECURE); + if (ctx) { + /* nothing to be done w/o ns context */ + return; + } qti_ns_ctx->spsr_el3 = read_ctx_reg(get_el3state_ctx(ctx), CTX_SPSR_EL3); diff --git a/plat/qti/sc7280/inc/platform_def.h b/plat/qti/sc7280/inc/platform_def.h new file mode 100644 index 000000000..660cb33a7 --- /dev/null +++ b/plat/qti/sc7280/inc/platform_def.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +/* Enable the dynamic translation tables library. */ +#define PLAT_XLAT_TABLES_DYNAMIC 1 + +#include + +#include +#include + +/*----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*/ +/* + * MPIDR_PRIMARY_CPU + * You just need to have the correct core_affinity_val i.e. [7:0] + * and cluster_affinity_val i.e. [15:8] + * the other bits will be ignored + */ +/*----------------------------------------------------------------------------*/ +#define MPIDR_PRIMARY_CPU 0x0000 +/*----------------------------------------------------------------------------*/ + +#define QTI_PWR_LVL0 MPIDR_AFFLVL0 +#define QTI_PWR_LVL1 MPIDR_AFFLVL1 +#define QTI_PWR_LVL2 MPIDR_AFFLVL2 +#define QTI_PWR_LVL3 MPIDR_AFFLVL3 + +/* + * Macros for local power states encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define QTI_LOCAL_STATE_RUN 0 +/* + * Local power state for clock-gating. Valid only for CPU and not cluster power + * domains + */ +#define QTI_LOCAL_STATE_STB 1 +/* + * Local power state for retention. Valid for CPU and cluster power + * domains + */ +#define QTI_LOCAL_STATE_RET 2 +/* + * Local power state for OFF/power down. Valid for CPU, cluster, RSC and PDC + * power domains + */ +#define QTI_LOCAL_STATE_OFF 3 +/* + * Local power state for DEEPOFF/power rail down. Valid for CPU, cluster and RSC + * power domains + */ +#define QTI_LOCAL_STATE_DEEPOFF 4 + +/* + * This macro defines the deepest retention state possible. A higher state + * id will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE QTI_LOCAL_STATE_RET + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE QTI_LOCAL_STATE_DEEPOFF + +/****************************************************************************** + * Required platform porting definitions common to all ARM standard platforms + *****************************************************************************/ + +/* + * Platform specific page table and MMU setup constants. + */ +#define MAX_MMAP_REGIONS (PLAT_QTI_MMAP_ENTRIES) + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36) + +#define ARM_CACHE_WRITEBACK_SHIFT 6 + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_GRANULE (1 << ARM_CACHE_WRITEBACK_SHIFT) + +/* + * One cache line needed for bakery locks on ARM platforms + */ +#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE) + +/*----------------------------------------------------------------------------*/ +/* PSCI power domain topology definitions */ +/*----------------------------------------------------------------------------*/ +/* One domain each to represent RSC and PDC level */ +#define PLAT_PDC_COUNT 1 +#define PLAT_RSC_COUNT 1 + +/* There is one top-level FCM cluster */ +#define PLAT_CLUSTER_COUNT 1 + +/* No. of cores in the FCM cluster */ +#define PLAT_CLUSTER0_CORE_COUNT 8 + +#define PLATFORM_CORE_COUNT (PLAT_CLUSTER0_CORE_COUNT) + +#define PLAT_NUM_PWR_DOMAINS (PLAT_PDC_COUNT +\ + PLAT_RSC_COUNT +\ + PLAT_CLUSTER_COUNT +\ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_PWR_LVL 3 + +/*****************************************************************************/ +/* Memory mapped Generic timer interfaces */ +/*****************************************************************************/ + +/*----------------------------------------------------------------------------*/ +/* GIC-600 constants */ +/*----------------------------------------------------------------------------*/ +#define BASE_GICD_BASE 0x17A00000 +#define BASE_GICR_BASE 0x17A60000 +#define BASE_GICC_BASE 0x0 +#define BASE_GICH_BASE 0x0 +#define BASE_GICV_BASE 0x0 + +#define QTI_GICD_BASE BASE_GICD_BASE +#define QTI_GICR_BASE BASE_GICR_BASE +#define QTI_GICC_BASE BASE_GICC_BASE + +/*----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------*/ +/* UART related constants. */ +/*----------------------------------------------------------------------------*/ +/* BASE ADDRESS OF DIFFERENT REGISTER SPACES IN HW */ +#define GENI4_CFG 0x0 +#define GENI4_IMAGE_REGS 0x100 +#define GENI4_DATA 0x600 + +/* COMMON STATUS/CONFIGURATION REGISTERS AND MASKS */ +#define GENI_STATUS_REG (GENI4_CFG + 0x00000040) +#define GENI_STATUS_M_GENI_CMD_ACTIVE_MASK (0x1) +#define UART_TX_TRANS_LEN_REG (GENI4_IMAGE_REGS + 0x00000170) +/* MASTER/TX ENGINE REGISTERS */ +#define GENI_M_CMD0_REG (GENI4_DATA + 0x00000000) +/* FIFO, STATUS REGISTERS AND MASKS */ +#define GENI_TX_FIFOn_REG (GENI4_DATA + 0x00000100) + +#define GENI_M_CMD_TX (0x08000000) + +/*----------------------------------------------------------------------------*/ +/* Device address space for mapping. Excluding starting 4K */ +/*----------------------------------------------------------------------------*/ +#define QTI_DEVICE_BASE 0x1000 +#define QTI_DEVICE_SIZE (0x80000000 - QTI_DEVICE_BASE) + +/******************************************************************************* + * BL31 specific defines. + ******************************************************************************/ +/* + * Put BL31 at DDR as per memory map. BL31_BASE is calculated using the + * current BL31 debug size plus a little space for growth. + */ +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/*----------------------------------------------------------------------------*/ +/* AOSS registers */ +/*----------------------------------------------------------------------------*/ +#define QTI_PS_HOLD_REG 0x0C264000 +/*----------------------------------------------------------------------------*/ +/* AOP CMD DB address space for mapping */ +/*----------------------------------------------------------------------------*/ +#define QTI_AOP_CMD_DB_BASE 0x80860000 +#define QTI_AOP_CMD_DB_SIZE 0x00020000 +/*----------------------------------------------------------------------------*/ +/* SOC hw version register */ +/*----------------------------------------------------------------------------*/ +#define QTI_SOC_VERSION U(0x7280) +#define QTI_SOC_VERSION_MASK U(0xFFFF) +#define QTI_SOC_REVISION_REG 0x1FC8000 +#define QTI_SOC_REVISION_MASK U(0xFFFF) +/*----------------------------------------------------------------------------*/ + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/qti/sc7280/inc/qti_rng_io.h b/plat/qti/sc7280/inc/qti_rng_io.h new file mode 100644 index 000000000..0f41fd6b8 --- /dev/null +++ b/plat/qti/sc7280/inc/qti_rng_io.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef QTI_RNG_IO_H +#define QTI_RNG_IO_H + +#define SEC_PRNG_STATUS 0x10D1004 +#define SEC_PRNG_STATUS_DATA_AVAIL_BMSK 0x1 +#define SEC_PRNG_DATA_OUT 0x10D1000 + + +#endif /* QTI_RNG_IO_H */ + diff --git a/plat/qti/sc7280/inc/qti_secure_io_cfg.h b/plat/qti/sc7280/inc/qti_secure_io_cfg.h new file mode 100644 index 000000000..058c5b554 --- /dev/null +++ b/plat/qti/sc7280/inc/qti_secure_io_cfg.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef QTI_SECURE_IO_CFG_H +#define QTI_SECURE_IO_CFG_H + +#include + +/* + * List of peripheral/IO memory areas that are protected from + * non-secure world but not required to be secure. + */ + +#define APPS_SMMU_TBU_PWR_STATUS 0x15002204 +#define APPS_SMMU_CUSTOM_CFG 0x15002300 +#define APPS_SMMU_STATS_SYNC_INV_TBU_ACK 0x150025DC +#define APPS_SMMU_SAFE_SEC_CFG 0x15002648 +#define APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR 0x15002670 + +static const uintptr_t qti_secure_io_allowed_regs[] = { + APPS_SMMU_TBU_PWR_STATUS, + APPS_SMMU_CUSTOM_CFG, + APPS_SMMU_STATS_SYNC_INV_TBU_ACK, + APPS_SMMU_SAFE_SEC_CFG, + APPS_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR, +}; + +#endif /* QTI_SECURE_IO_CFG_H */ diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk new file mode 100644 index 000000000..6e267816a --- /dev/null +++ b/plat/qti/sc7280/platform.mk @@ -0,0 +1,119 @@ +# +# Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Make for SC7280 QTI platform. + +QTI_PLAT_PATH := plat/qti +CHIPSET := ${PLAT} + +# Turn On Separate code & data. +SEPARATE_CODE_AND_RODATA := 1 +USE_COHERENT_MEM := 1 +WARMBOOT_ENABLE_DCACHE_EARLY := 1 + +# Disable the PSCI platform compatibility layer +ENABLE_PLAT_COMPAT := 0 + +# Enable PSCI v1.0 extended state ID format +PSCI_EXTENDED_STATE_ID := 1 +ARM_RECOM_STATE_ID_ENC := 1 + +COLD_BOOT_SINGLE_CPU := 1 +PROGRAMMABLE_RESET_ADDRESS := 1 + +RESET_TO_BL31 := 0 + +MULTI_CONSOLE_API := 1 + +QTI_SDI_BUILD := 0 +$(eval $(call assert_boolean,QTI_SDI_BUILD)) +$(eval $(call add_define,QTI_SDI_BUILD)) + +#disable CTX_INCLUDE_AARCH32_REGS to support sc7280 gold cores +override CTX_INCLUDE_AARCH32_REGS := 0 +WORKAROUND_CVE_2017_5715 := 0 +DYNAMIC_WORKAROUND_CVE_2018_3639 := 1 +# Enable stack protector. +ENABLE_STACK_PROTECTOR := strong + + +QTI_EXTERNAL_INCLUDES := -I${QTI_PLAT_PATH}/${CHIPSET}/inc \ + -I${QTI_PLAT_PATH}/common/inc \ + -I${QTI_PLAT_PATH}/common/inc/$(ARCH) \ + -I${QTI_PLAT_PATH}/qtiseclib/inc \ + -I${QTI_PLAT_PATH}/qtiseclib/inc/${CHIPSET} \ + +QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \ + $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_silver.S \ + $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_gold.S \ + $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \ + $(QTI_PLAT_PATH)/common/src/pm8998.c \ + $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \ + $(QTI_PLAT_PATH)/common/src/qti_common.c \ + $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \ + $(QTI_PLAT_PATH)/common/src/qti_gic_v3.c \ + $(QTI_PLAT_PATH)/common/src/qti_interrupt_svc.c \ + $(QTI_PLAT_PATH)/common/src/qti_syscall.c \ + $(QTI_PLAT_PATH)/common/src/qti_topology.c \ + $(QTI_PLAT_PATH)/common/src/qti_pm.c \ + $(QTI_PLAT_PATH)/common/src/qti_rng.c \ + $(QTI_PLAT_PATH)/common/src/spmi_arb.c \ + $(QTI_PLAT_PATH)/qtiseclib/src/qtiseclib_cb_interface.c \ + + +PLAT_INCLUDES := -Iinclude/plat/common/ \ + +PLAT_INCLUDES += ${QTI_EXTERNAL_INCLUDES} + +include lib/xlat_tables_v2/xlat_tables.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} \ + plat/common/aarch64/crash_console_helpers.S \ + common/desc_image_load.c \ + lib/bl_aux_params/bl_aux_params.c \ + +include lib/coreboot/coreboot.mk + +#PSCI Sources. +PSCI_SOURCES := plat/common/plat_psci_common.c \ + +# GIC-600 configuration +GICV3_SUPPORT_GIC600 := 1 +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + +#Timer sources +TIMER_SOURCES := drivers/delay_timer/generic_delay_timer.c \ + drivers/delay_timer/delay_timer.c \ + +#GIC sources. +GIC_SOURCES := plat/common/plat_gicv3.c \ + ${GICV3_SOURCES} \ + +BL31_SOURCES += ${QTI_BL31_SOURCES} \ + ${PSCI_SOURCES} \ + ${GIC_SOURCES} \ + ${TIMER_SOURCES} \ + +LIB_QTI_PATH := ${QTI_PLAT_PATH}/qtiseclib/lib/${CHIPSET} + + +# Override this on the command line to point to the qtiseclib library which +# will be available in coreboot.org +QTISECLIB_PATH ?= + +ifeq ($(QTISECLIB_PATH),) +# if No lib then use stub implementation for qtiseclib interface +$(warning QTISECLIB_PATH is not provided while building, using stub implementation. \ + Please refer docs/plat/qti.rst for more details \ + THIS FIRMWARE WILL NOT BOOT!) +BL31_SOURCES += plat/qti/qtiseclib/src/qtiseclib_interface_stub.c +else +# use library provided by QTISECLIB_PATH +LDFLAGS += -L $(dir $(QTISECLIB_PATH)) +LDLIBS += -l$(patsubst lib%.a,%,$(notdir $(QTISECLIB_PATH))) +endif + -- cgit v1.2.3 From 45fa189544969edf55496ee209f3ee4417508621 Mon Sep 17 00:00:00 2001 From: Saurabh Gorecha Date: Wed, 15 Sep 2021 00:27:23 +0530 Subject: docs(maintainers): update qti maintainer Add lachit and Sreevyshanavi in qti maintainer Signed-off-by: Saurabh Gorecha Change-Id: I48d2378551775a3ad63bc7c3a4e2b62b15c4770d --- docs/about/maintainers.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 07f258c77..1bd46663a 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -535,7 +535,10 @@ QTI platform port ^^^^^^^^^^^^^^^^^ :|M|: Saurabh Gorecha :|G|: `sgorecha`_ -:|M|: Debasish Mandal +:|M|: Lachit Patel +:|G|: `lachitp`_ +:|M|: Sreevyshanavi Kare +:|G|: `sreekare`_ :|M|: QTI TF Maintainers :|F|: docs/plat/qti.rst :|F|: plat/qti/ @@ -732,6 +735,7 @@ Threat Model .. _jenswi-linaro: https://github.com/jenswi-linaro .. _jwerner-chromium: https://github.com/jwerner-chromium .. _kostapr: https://github.com/kostapr +.. _lachitp: https://github.com/lachitp .. _ldts: https://github.com/ldts .. _marex: https://github.com/marex .. _masahir0y: https://github.com/masahir0y @@ -750,6 +754,7 @@ Threat Model .. _shawnguo2: https://github.com/shawnguo2 .. _smaeul: https://github.com/smaeul .. _soby-mathew: https://github.com/soby-mathew +.. _sreekare: https://github.com/sreekare .. _thloh85-intel: https://github.com/thloh85-intel .. _thomas-arm: https://github.com/thomas-arm .. _TonyXie06: https://github.com/TonyXie06 -- cgit v1.2.3 From ff18c4cde4360cf365743d38f1eaad45b1ebd992 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Oct 2020 14:32:26 +0200 Subject: refactor(drivers/st/clk): change fdt_get_rcc_node as static Change the fdt_get_rcc_node function to static, as it is used only in stm32mp_clkfunc.c file; it is only a cleanup change without functional modification. Signed-off-by: Patrick Delaunay Change-Id: Ib4ef110f6f1b16dbaa727a065e40275d3cf58a73 --- drivers/st/clk/stm32mp_clkfunc.c | 2 +- include/drivers/st/stm32mp_clkfunc.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 8333f6dfb..2101171a3 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -161,7 +161,7 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, * @param fdt: Device tree reference * @return: Node offset or a negative value on error */ -int fdt_get_rcc_node(void *fdt) +static int fdt_get_rcc_node(void *fdt) { return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); } diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h index c7e0b6e6f..c3329cc71 100644 --- a/include/drivers/st/stm32mp_clkfunc.h +++ b/include/drivers/st/stm32mp_clkfunc.h @@ -19,7 +19,6 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, const char *prop_name, uint32_t dflt_value); -int fdt_get_rcc_node(void *fdt); int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, uint32_t *array); int fdt_rcc_subnode_offset(const char *name); -- cgit v1.2.3 From 9d250f03d7a38cac86655495879b2151b877db0d Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Fri, 10 Sep 2021 14:57:49 +0800 Subject: feat(plat/nxp/ls1028a): add ls1028a soc support The QorIQ LS1028A processor integrates two 64-bit ARM Cortex-A72 cores with a GPU and LCD controller, as well as a TSNenabled Ethernet port and a TSN-enabled switch with four external ports. Signed-off-by: Ruchika Gupta Signed-off-by: Pankaj Gupta Signed-off-by: Jiafei Pan Signed-off-by: Yangbo Lu Signed-off-by: Ran Wang Change-Id: I9f65c6af5db7e20702828cd208290c1b43a54941 --- plat/nxp/soc-ls1028a/aarch64/ls1028a.S | 1387 ++++++++++++++++++++++++ plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S | 70 ++ plat/nxp/soc-ls1028a/include/soc.h | 149 +++ plat/nxp/soc-ls1028a/soc.c | 420 +++++++ plat/nxp/soc-ls1028a/soc.def | 95 ++ plat/nxp/soc-ls1028a/soc.mk | 113 ++ 6 files changed, 2234 insertions(+) create mode 100644 plat/nxp/soc-ls1028a/aarch64/ls1028a.S create mode 100644 plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S create mode 100644 plat/nxp/soc-ls1028a/include/soc.h create mode 100644 plat/nxp/soc-ls1028a/soc.c create mode 100644 plat/nxp/soc-ls1028a/soc.def create mode 100644 plat/nxp/soc-ls1028a/soc.mk diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S new file mode 100644 index 000000000..404c39ec9 --- /dev/null +++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a.S @@ -0,0 +1,1387 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .section .text, "ax" + +#include + +#include +#include +#include +#include + +#include +#include +#include + + .global soc_init_lowlevel + .global soc_init_percpu + .global _set_platform_security + .global _soc_set_start_addr + + .global _soc_core_release + .global _soc_ck_disabled + .global _soc_core_restart + .global _soc_core_prep_off + .global _soc_core_entr_off + .global _soc_core_exit_off + .global _soc_sys_reset + .global _soc_sys_off + .global _soc_core_prep_stdby + .global _soc_core_entr_stdby + .global _soc_core_exit_stdby + .global _soc_core_prep_pwrdn + .global _soc_core_entr_pwrdn + .global _soc_core_exit_pwrdn + .global _soc_clstr_prep_stdby + .global _soc_clstr_exit_stdby + .global _soc_clstr_prep_pwrdn + .global _soc_clstr_exit_pwrdn + .global _soc_sys_prep_stdby + .global _soc_sys_exit_stdby + .global _soc_sys_prep_pwrdn + .global _soc_sys_pwrdn_wfi + .global _soc_sys_exit_pwrdn + + .equ TZPCDECPROT_0_SET_BASE, 0x02200804 + .equ TZPCDECPROT_1_SET_BASE, 0x02200810 + .equ TZPCDECPROT_2_SET_BASE, 0x0220081C + + .equ TZASC_REGION_ATTRIBUTES_0_0, 0x01100110 + +/* + * This function initialize the soc. + * in: void + * out: void + * uses x0 - x11 + */ +func soc_init_lowlevel + /* + * Called from C, so save the non-volatile regs + * save these as pairs of registers to maintain the + * required 16-byte alignment on the stack + */ + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + stp x8, x9, [sp, #-16]! + stp x10, x11, [sp, #-16]! + stp x12, x13, [sp, #-16]! + stp x18, x30, [sp, #-16]! + + /* + * Make sure the personality has been established by releasing cores + * that are marked "to-be-disabled" from reset + */ + bl release_disabled /* 0-8 */ + + /* Set SCRATCHRW7 to 0x0 */ + ldr x0, =DCFG_SCRATCHRW7_OFFSET + mov x1, xzr + bl _write_reg_dcfg + + /* Restore the aarch32/64 non-volatile registers */ + ldp x18, x30, [sp], #16 + ldp x12, x13, [sp], #16 + ldp x10, x11, [sp], #16 + ldp x8, x9, [sp], #16 + ldp x6, x7, [sp], #16 + ldp x4, x5, [sp], #16 + ret +endfunc soc_init_lowlevel + +/* + * void soc_init_percpu(void) + * + * This function performs any soc-specific initialization that is needed on + * a per-core basis + * in: none + * out: none + * uses x0 - x3 + */ +func soc_init_percpu + stp x4, x30, [sp, #-16]! + + bl plat_my_core_mask + mov x2, x0 + + /* x2 = core mask */ + + /* see if this core is marked for prefetch disable */ + mov x0, #PREFETCH_DIS_OFFSET + bl _get_global_data /* 0-1 */ + tst x0, x2 + b.eq 1f + bl _disable_ldstr_pfetch_A72 /* 0 */ +1: + mov x0, #NXP_PMU_ADDR + bl enable_timer_base_to_cluster + + ldp x4, x30, [sp], #16 + ret +endfunc soc_init_percpu + +/* + * This function determines if a core is disabled via COREDISABLEDSR + * in: w0 = core_mask_lsb + * out: w0 = 0, core not disabled + * w0 != 0, core disabled + * uses x0, x1 + */ +func _soc_ck_disabled + /* get base addr of dcfg block */ + ldr x1, =NXP_DCFG_ADDR + + /* read COREDISABLEDSR */ + ldr w1, [x1, #DCFG_COREDISABLEDSR_OFFSET] + + /* test core bit */ + and w0, w1, w0 + + ret +endfunc _soc_ck_disabled + +/* + * This function sets the security mechanisms in the SoC to implement the + * Platform Security Policy + */ +func _set_platform_security + mov x3, x30 + +#if (!SUPPRESS_TZC) + /* initialize the tzpc */ + bl init_tzpc +#endif + +#if (!SUPPRESS_SEC) + /* initialize secmon */ + bl initSecMon +#endif + + mov x30, x3 + ret +endfunc _set_platform_security + +/* + * Part of CPU_ON + * + * This function releases a secondary core from reset + * in: x0 = core_mask_lsb + * out: none + * uses: x0 - x3 + */ +_soc_core_release: + mov x3, x30 + + /* + * Write to CORE_HOLD to tell the bootrom that we want this core + * to run + */ + ldr x1, =NXP_SEC_REGFILE_ADDR + str w0, [x1, #CORE_HOLD_OFFSET] + + /* Read-modify-write BRRL to release core */ + mov x1, #NXP_RESET_ADDR + ldr w2, [x1, #BRR_OFFSET] + orr w2, w2, w0 + str w2, [x1, #BRR_OFFSET] + dsb sy + isb + + /* Send event */ + sev + isb + + mov x30, x3 + ret + +/* + * This function writes a 64-bit address to bootlocptrh/l + * in: x0, 64-bit address to write to BOOTLOCPTRL/H + * uses x0, x1, x2 + */ +func _soc_set_start_addr + /* Get the 64-bit base address of the dcfg block */ + ldr x2, =NXP_DCFG_ADDR + + /* Write the 32-bit BOOTLOCPTRL register */ + mov x1, x0 + str w1, [x2, #DCFG_BOOTLOCPTRL_OFFSET] + + /* Write the 32-bit BOOTLOCPTRH register */ + lsr x1, x0, #32 + str w1, [x2, #DCFG_BOOTLOCPTRH_OFFSET] + ret +endfunc _soc_set_start_addr + +/* + * Part of CPU_ON + * + * This function restarts a core shutdown via _soc_core_entr_off + * in: x0 = core mask lsb (of the target cpu) + * out: x0 == 0, on success + * x0 != 0, on failure + * uses x0 - x6 + */ +_soc_core_restart: + mov x6, x30 + mov x4, x0 + + /* pgm GICD_CTLR - enable secure grp0 */ + mov x5, #NXP_GICD_ADDR + ldr w2, [x5, #GICD_CTLR_OFFSET] + orr w2, w2, #GICD_CTLR_EN_GRP_0 + str w2, [x5, #GICD_CTLR_OFFSET] + dsb sy + isb + + /* Poll on RWP til write completes */ +4: + ldr w2, [x5, #GICD_CTLR_OFFSET] + tst w2, #GICD_CTLR_RWP + b.ne 4b + + /* + * x4 = core mask lsb + * x5 = gicd base addr + */ + + mov x0, x4 + bl get_mpidr_value + + /* Generate target list bit */ + and x1, x0, #MPIDR_AFFINITY0_MASK + mov x2, #1 + lsl x2, x2, x1 + + /* Get the affinity1 field */ + and x1, x0, #MPIDR_AFFINITY1_MASK + lsl x1, x1, #8 + orr x2, x2, x1 + + /* Insert the INTID for SGI15 */ + orr x2, x2, #ICC_SGI0R_EL1_INTID + + /* Fire the SGI */ + msr ICC_SGI0R_EL1, x2 + dsb sy + isb + + /* Load '0' on success */ + mov x0, xzr + + mov x30, x6 + ret + +/* + * Part of CPU_OFF + * + * This function programs SoC & GIC registers in preparation for shutting down + * the core + * in: x0 = core mask lsb + * out: none + * uses x0 - x7 + */ +_soc_core_prep_off: + mov x8, x30 + mov x7, x0 + + /* x7 = core mask lsb */ + + mrs x1, CPUECTLR_EL1 + + /* Set smp and disable L2 snoops in cpuectlr */ + orr x1, x1, #CPUECTLR_SMPEN_EN + orr x1, x1, #CPUECTLR_DISABLE_TWALK_PREFETCH + bic x1, x1, #CPUECTLR_INS_PREFETCH_MASK + bic x1, x1, #CPUECTLR_DAT_PREFETCH_MASK + + /* Set retention control in cpuectlr */ + bic x1, x1, #CPUECTLR_TIMER_MASK + orr x1, x1, #CPUECTLR_TIMER_2TICKS + msr CPUECTLR_EL1, x1 + + /* Get redistributor rd base addr for this core */ + mov x0, x7 + bl get_gic_rd_base + mov x6, x0 + + /* Get redistributor sgi base addr for this core */ + mov x0, x7 + bl get_gic_sgi_base + mov x5, x0 + + /* + * x5 = gicr sgi base addr + * x6 = gicr rd base addr + * x7 = core mask lsb + */ + + /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */ + mov w3, #GICR_ICENABLER0_SGI15 + str w3, [x5, #GICR_ICENABLER0_OFFSET] +2: + /* Poll on rwp bit in GICR_CTLR */ + ldr w4, [x6, #GICR_CTLR_OFFSET] + tst w4, #GICR_CTLR_RWP + b.ne 2b + + /* Disable GRP1 interrupts at cpu interface */ + msr ICC_IGRPEN1_EL3, xzr + + /* Disable GRP0 ints at cpu interface */ + msr ICC_IGRPEN0_EL1, xzr + + /* Program the redistributor - poll on GICR_CTLR.RWP as needed */ + + /* Define SGI 15 as Grp0 - GICR_IGROUPR0 */ + ldr w4, [x5, #GICR_IGROUPR0_OFFSET] + bic w4, w4, #GICR_IGROUPR0_SGI15 + str w4, [x5, #GICR_IGROUPR0_OFFSET] + + /* Define SGI 15 as Grp0 - GICR_IGRPMODR0 */ + ldr w3, [x5, #GICR_IGRPMODR0_OFFSET] + bic w3, w3, #GICR_IGRPMODR0_SGI15 + str w3, [x5, #GICR_IGRPMODR0_OFFSET] + + /* Set priority of SGI 15 to highest (0x0) - GICR_IPRIORITYR3 */ + ldr w4, [x5, #GICR_IPRIORITYR3_OFFSET] + bic w4, w4, #GICR_IPRIORITYR3_SGI15_MASK + str w4, [x5, #GICR_IPRIORITYR3_OFFSET] + + /* Enable SGI 15 at redistributor - GICR_ISENABLER0 */ + mov w3, #GICR_ISENABLER0_SGI15 + str w3, [x5, #GICR_ISENABLER0_OFFSET] + dsb sy + isb +3: + /* Poll on rwp bit in GICR_CTLR */ + ldr w4, [x6, #GICR_CTLR_OFFSET] + tst w4, #GICR_CTLR_RWP + b.ne 3b + + /* Quiesce the debug interfaces */ + mrs x3, osdlr_el1 + orr x3, x3, #OSDLR_EL1_DLK_LOCK + msr osdlr_el1, x3 + isb + + /* Enable grp0 ints */ + mov x3, #ICC_IGRPEN0_EL1_EN + msr ICC_IGRPEN0_EL1, x3 + + /* + * x5 = gicr sgi base addr + * x6 = gicr rd base addr + * x7 = core mask lsb + */ + + /* Clear any pending interrupts */ + mvn w1, wzr + str w1, [x5, #GICR_ICPENDR0_OFFSET] + + /* Make sure system counter is enabled */ + ldr x3, =NXP_TIMER_ADDR + ldr w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] + tst w0, #SYS_COUNTER_CNTCR_EN + b.ne 4f + orr w0, w0, #SYS_COUNTER_CNTCR_EN + str w0, [x3, #SYS_COUNTER_CNTCR_OFFSET] +4: + /* Enable the core timer and mask timer interrupt */ + mov x1, #CNTP_CTL_EL0_EN + orr x1, x1, #CNTP_CTL_EL0_IMASK + msr cntp_ctl_el0, x1 + + isb + mov x30, x8 + ret + +/* + * Part of CPU_OFF + * + * This function performs the final steps to shutdown the core + * in: x0 = core mask lsb + * out: none + * uses x0 - x5 + */ +_soc_core_entr_off: + mov x5, x30 + mov x4, x0 + + /* x4 = core mask */ +1: + /* Enter low-power state by executing wfi */ + wfi + + /* See if SGI15 woke us up */ + mrs x2, ICC_IAR0_EL1 + mov x3, #ICC_IAR0_EL1_SGI15 + cmp x2, x3 + b.ne 1b + + /* Deactivate the int */ + msr ICC_EOIR0_EL1, x2 + + /* x4 = core mask */ +2: + /* Check if core has been turned on */ + mov x0, x4 + bl _getCoreState + + /* x0 = core state */ + + cmp x0, #CORE_WAKEUP + b.ne 1b + + /* If we get here, then we have exited the wfi */ + mov x30, x5 + ret + +/* + * Part of CPU_OFF + * + * This function starts the process of starting a core back up + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4, x5, x6 + */ +_soc_core_exit_off: + mov x6, x30 + mov x5, x0 + + /* Disable forwarding of GRP0 ints at cpu interface */ + msr ICC_IGRPEN0_EL1, xzr + + /* Get redistributor sgi base addr for this core */ + mov x0, x5 + bl get_gic_sgi_base + mov x4, x0 + + /* x4 = gicr sgi base addr */ + /* x5 = core mask */ + + /* Disable SGI 15 at redistributor - GICR_ICENABLER0 */ + mov w1, #GICR_ICENABLER0_SGI15 + str w1, [x4, #GICR_ICENABLER0_OFFSET] + + /* Get redistributor rd base addr for this core */ + mov x0, x5 + bl get_gic_rd_base + mov x4, x0 + + /* x4 = gicr rd base addr */ +2: + /* Poll on rwp bit in GICR_CTLR */ + ldr w2, [x4, #GICR_CTLR_OFFSET] + tst w2, #GICR_CTLR_RWP + b.ne 2b + + /* x4 = gicr rd base addr */ + + /* Unlock the debug interfaces */ + mrs x3, osdlr_el1 + bic x3, x3, #OSDLR_EL1_DLK_LOCK + msr osdlr_el1, x3 + isb + + dsb sy + isb + mov x30, x6 + ret + +/* + * This function requests a reset of the entire SOC + * in: none + * out: none + * uses: x0, x1, x2, x3, x4, x5, x6 + */ +_soc_sys_reset: + mov x3, x30 + + /* Make sure the mask is cleared in the reset request mask register */ + mov x0, #RST_RSTRQMR1_OFFSET + mov w1, wzr + bl _write_reg_reset + + /* Set the reset request */ + mov x4, #RST_RSTCR_OFFSET + mov x0, x4 + mov w1, #RSTCR_RESET_REQ + bl _write_reg_reset + + /* x4 = RST_RSTCR_OFFSET */ + + /* + * Just in case this address range is mapped as cacheable, + * flush the write out of the dcaches + */ + mov x2, #NXP_RESET_ADDR + add x2, x2, x4 + dc cvac, x2 + dsb st + isb + + /* This function does not return */ +1: + wfi + b 1b + +/* + * Part of SYSTEM_OFF + * + * This function turns off the SoC clocks + * Note: this function is not intended to return, and the only allowable + * recovery is POR + * in: none + * out: none + * uses x0, x1, x2, x3 + */ +_soc_sys_off: + /* + * Disable sec, spi and flexspi + * TBD - Check if eNETC needs to be disabled + */ + ldr x2, =NXP_DCFG_ADDR + ldr x0, =DCFG_DEVDISR1_OFFSET + ldr w1, =DCFG_DEVDISR1_SEC + str w1, [x2, x0] + ldr x0, =DCFG_DEVDISR4_OFFSET + ldr w1, =DCFG_DEVDISR4_SPI_QSPI + str w1, [x2, x0] + + /* Set TPMWAKEMR0 */ + ldr x0, =TPMWAKEMR0_ADDR + mov w1, #0x1 + str w1, [x0] + + /* Disable icache, dcache, mmu @ EL1 */ + mov x1, #SCTLR_I_C_M_MASK + mrs x0, sctlr_el1 + bic x0, x0, x1 + msr sctlr_el1, x0 + + /* Disable L2 prefetches */ + mrs x0, CPUECTLR_EL1 + orr x0, x0, #CPUECTLR_SMPEN_EN + bic x0, x0, #CPUECTLR_TIMER_MASK + orr x0, x0, #CPUECTLR_TIMER_2TICKS + msr CPUECTLR_EL1, x0 + dsb sy + isb + + /* Disable CCI snoop domain */ + ldr x0, =NXP_CCI_ADDR + mov w1, #0x1 + str w1, [x0] + + bl get_pmu_idle_core_mask + + /* x3 = pmu base addr */ + mov x3, #NXP_PMU_ADDR +4: + ldr w1, [x3, #PMU_PCPW20SR_OFFSET] + cmp w1, w0 + b.ne 4b + + bl get_pmu_idle_cluster_mask + mov x3, #NXP_PMU_ADDR + str w0, [x3, #PMU_CLAINACTSETR_OFFSET] + + bl get_pmu_idle_core_mask + mov x3, #NXP_PMU_ADDR +1: + ldr w1, [x3, #PMU_PCPW20SR_OFFSET] + cmp w1, w0 + b.ne 1b + + bl get_pmu_flush_cluster_mask + mov x3, #NXP_PMU_ADDR + str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET] +2: + ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET] + cmp w1, w0 + b.ne 2b + + str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET] + + str w0, [x3, #PMU_CLSINACTSETR_OFFSET] + + mov x2, #DAIF_SET_MASK + mrs x1, spsr_el1 + orr x1, x1, x2 + msr spsr_el1, x1 + + mrs x1, spsr_el2 + orr x1, x1, x2 + msr spsr_el2, x1 + + /* Force the debug interface to be quiescent */ + mrs x0, osdlr_el1 + orr x0, x0, #0x1 + msr osdlr_el1, x0 + + /* Invalidate all TLB entries at all 3 exception levels */ + tlbi alle1 + tlbi alle2 + tlbi alle3 + + /* x3 = pmu base addr */ + + /* Request lpm20 */ + ldr x0, =PMU_POWMGTCSR_OFFSET + ldr w1, =PMU_POWMGTCSR_VAL + str w1, [x3, x0] + isb + dsb sy +5: + wfe + b.eq 5b + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +_soc_core_prep_stdby: + /* Clear CPUECTLR_EL1[2:0] */ + mrs x1, CPUECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CPUECTLR_EL1, x1 + + ret + +/* + * Part of CPU_SUSPEND + * + * This function puts the calling core into standby state + * in: x0 = core mask lsb + * out: none + * uses x0 + */ +_soc_core_entr_stdby: + /* X0 = core mask lsb */ + dsb sy + isb + wfi + + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +_soc_core_exit_stdby: + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2 + */ +_soc_core_prep_pwrdn: + /* Make sure system counter is enabled */ + ldr x2, =NXP_TIMER_ADDR + ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] + tst w0, #SYS_COUNTER_CNTCR_EN + b.ne 1f + orr w0, w0, #SYS_COUNTER_CNTCR_EN + str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] +1: + /* + * Enable dynamic retention control (CPUECTLR[2:0]) + * Set the SMPEN bit (CPUECTLR[6]) + */ + mrs x1, CPUECTLR_EL1 + bic x1, x1, #CPUECTLR_RET_MASK + orr x1, x1, #CPUECTLR_TIMER_2TICKS + orr x1, x1, #CPUECTLR_SMPEN_EN + msr CPUECTLR_EL1, x1 + + isb + ret + +/* + * Part of CPU_SUSPEND + * + * This function puts the calling core into a power-down state + * in: x0 = core mask lsb + * out: none + * uses x0 + */ +_soc_core_entr_pwrdn: + /* X0 = core mask lsb */ + dsb sy + isb + wfi + + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after power-down state + * in: x0 = core mask lsb + * out: none + * uses none + */ +_soc_core_exit_pwrdn: + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +_soc_clstr_prep_stdby: + /* Clear CPUECTLR_EL1[2:0] */ + mrs x1, CPUECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CPUECTLR_EL1, x1 + + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +_soc_clstr_exit_stdby: + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2 + */ +_soc_clstr_prep_pwrdn: + /* Make sure system counter is enabled */ + ldr x2, =NXP_TIMER_ADDR + ldr w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] + tst w0, #SYS_COUNTER_CNTCR_EN + b.ne 1f + orr w0, w0, #SYS_COUNTER_CNTCR_EN + str w0, [x2, #SYS_COUNTER_CNTCR_OFFSET] +1: + /* + * Enable dynamic retention control (CPUECTLR[2:0]) + * Set the SMPEN bit (CPUECTLR[6]) + */ + mrs x1, CPUECTLR_EL1 + bic x1, x1, #CPUECTLR_RET_MASK + orr x1, x1, #CPUECTLR_TIMER_2TICKS + orr x1, x1, #CPUECTLR_SMPEN_EN + msr CPUECTLR_EL1, x1 + + isb + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after power-down state + * in: x0 = core mask lsb + * out: none + * uses none + */ +_soc_clstr_exit_pwrdn: + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to standby + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +_soc_sys_prep_stdby: + /* Clear CPUECTLR_EL1[2:0] */ + mrs x1, CPUECTLR_EL1 + bic x1, x1, #CPUECTLR_TIMER_MASK + msr CPUECTLR_EL1, x1 + + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after standby state + * in: x0 = core mask lsb + * out: none + * uses none + */ +_soc_sys_exit_stdby: + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs SoC-specific programming prior to + * suspend-to-power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1, x2, x3, x4 + */ +_soc_sys_prep_pwrdn: + /* Set retention control */ + mrs x0, CPUECTLR_EL1 + bic x0, x0, #CPUECTLR_TIMER_MASK + orr x0, x0, #CPUECTLR_TIMER_2TICKS + orr x0, x0, #CPUECTLR_SMPEN_EN + msr CPUECTLR_EL1, x0 + dsb sy + isb + ret + +/* + * Part of CPU_SUSPEND + * + * This function puts the calling core, and potentially the soc, into a + * low-power state + * in: x0 = core mask lsb + * out: x0 = 0, success + * x0 < 0, failure + * uses x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x13, x14, x15, + * x16, x17, x18 + */ +_soc_sys_pwrdn_wfi: + mov x18, x30 + + mov x3, #NXP_PMU_ADDR + + /* x3 = pmu base addr */ + + /* Backup epu registers to stack */ + ldr x2, =NXP_EPU_ADDR + ldr w4, [x2, #EPU_EPIMCR10_OFFSET] + ldr w5, [x2, #EPU_EPCCR10_OFFSET] + ldr w6, [x2, #EPU_EPCTR10_OFFSET] + ldr w7, [x2, #EPU_EPGCR_OFFSET] + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + + /* + * x2 = epu base addr + * x3 = pmu base addr + */ + + /* Set up EPU event to receive the wake signal from PMU */ + mov w4, #EPU_EPIMCR10_VAL + mov w5, #EPU_EPCCR10_VAL + mov w6, #EPU_EPCTR10_VAL + mov w7, #EPU_EPGCR_VAL + str w4, [x2, #EPU_EPIMCR10_OFFSET] + str w5, [x2, #EPU_EPCCR10_OFFSET] + str w6, [x2, #EPU_EPCTR10_OFFSET] + str w7, [x2, #EPU_EPGCR_OFFSET] + + ldr x2, =NXP_GICD_ADDR + + /* + * x2 = gicd base addr + * x3 = pmu base addr + */ + + /* Backup flextimer/mmc/usb interrupt router */ + ldr x0, =GICD_IROUTER60_OFFSET + ldr x1, =GICD_IROUTER76_OFFSET + ldr w4, [x2, x0] + ldr w5, [x2, x1] + ldr x0, =GICD_IROUTER112_OFFSET + ldr x1, =GICD_IROUTER113_OFFSET + ldr w6, [x2, x0] + ldr w7, [x2, x1] + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + + /* + * x2 = gicd base addr + * x3 = pmu base addr + * x0 = GICD_IROUTER112_OFFSET + * x1 = GICD_IROUTER113_OFFSET + */ + + /* Re-route interrupt to cluster 1 */ + ldr w4, =GICD_IROUTER_VALUE + str w4, [x2, x0] + str w4, [x2, x1] + ldr x0, =GICD_IROUTER60_OFFSET + ldr x1, =GICD_IROUTER76_OFFSET + str w4, [x2, x0] + str w4, [x2, x1] + dsb sy + isb + + /* x3 = pmu base addr */ + + /* Disable sec, Check for eNETC, spi and qspi */ + ldr x2, =NXP_DCFG_ADDR + ldr x0, =DCFG_DEVDISR1_OFFSET + ldr w1, =DCFG_DEVDISR1_SEC + str w1, [x2, x0] + + ldr x0, =DCFG_DEVDISR4_OFFSET + ldr w1, =DCFG_DEVDISR4_SPI_QSPI + str w1, [x2, x0] + + /* x3 = pmu base addr */ + + /* Set TPMWAKEMR0 */ + ldr x0, =TPMWAKEMR0_ADDR + mov w1, #0x1 + str w1, [x0] + + /* Disable CCI snoop domain */ + ldr x0, =NXP_CCI_ADDR + mov w1, #0x1 + str w1, [x0] + + /* Setup retention control */ + mrs x0, CPUECTLR_EL1 + orr x0, x0, #CPUECTLR_SMPEN_EN + orr x0, x0, #CPUECTLR_TIMER_2TICKS + msr CPUECTLR_EL1, x0 + dsb sy + isb + + bl get_pmu_idle_core_mask + mov x3, #NXP_PMU_ADDR +8: + ldr w1, [x3, #PMU_PCPW20SR_OFFSET] + cmp w1, w0 + b.ne 8b + + /* x3 = NXP_PMU_ADDR */ + /* 1 cluster SoC */ + + bl get_pmu_idle_cluster_mask + mov x3, #NXP_PMU_ADDR + + str w0, [x3, #PMU_CLAINACTSETR_OFFSET] + + bl get_pmu_idle_core_mask + /* x3 = NXP_PMU_ADDR */ + mov x3, #NXP_PMU_ADDR +1: + ldr w1, [x3, #PMU_PCPW20SR_OFFSET] + cmp w1, w0 + b.ne 1b + + /* x3 = NXP_PMU_ADDR */ + bl get_pmu_flush_cluster_mask + mov x3, #NXP_PMU_ADDR + + str w0, [x3, #PMU_CLL2FLUSHSETR_OFFSET] + + /* x3 = NXP_PMU_ADDR */ +2: + ldr w1, [x3, #PMU_CLL2FLUSHSR_OFFSET] + cmp w1, w0 + b.ne 2b + + /* x3 = NXP_PMU_ADDR */ + + str w0, [x3, #PMU_CLSL2FLUSHCLRR_OFFSET] + + str w0, [x3, #PMU_CLSINACTSETR_OFFSET] + + /* Force the debug interface to be quiescent */ + mrs x0, osdlr_el1 + orr x0, x0, #0x1 + msr osdlr_el1, x0 + + /* + * Enable the WakeRequest signal + * x3 is cpu mask starting from cpu1 to cpu0 + */ + bl get_tot_num_cores + sub x0, x0, #1 + mov x3, #0x1 + lsl x3, x3, x0 +2: + mov x0, x3 + bl get_gic_rd_base // 0-2 + ldr w1, [x0, #GICR_WAKER_OFFSET] + orr w1, w1, #GICR_WAKER_SLEEP_BIT + str w1, [x0, #GICR_WAKER_OFFSET] +1: + ldr w1, [x0, #GICR_WAKER_OFFSET] + cmp w1, #GICR_WAKER_ASLEEP + b.ne 1b + + lsr x3, x3, #1 + cbnz x3, 2b + + /* Invalidate all TLB entries at all 3 exception levels */ + tlbi alle1 + tlbi alle2 + tlbi alle3 + + /* Request lpm20 */ + mov x3, #NXP_PMU_ADDR + ldr x0, =PMU_POWMGTCSR_OFFSET + ldr w1, =PMU_POWMGTCSR_VAL + str w1, [x3, x0] + + ldr x5, =NXP_EPU_ADDR +4: + wfe + ldr w1, [x5, #EPU_EPCTR10_OFFSET] + cmp w1, #0 + b.eq 4b + + /* x3 = NXP_PMU_ADDR */ + + bl get_pmu_idle_cluster_mask + mov x3, NXP_PMU_ADDR + + /* Re-enable the GPP ACP */ + str w0, [x3, #PMU_CLAINACTCLRR_OFFSET] + str w0, [x3, #PMU_CLSINACTCLRR_OFFSET] + + /* x3 = NXP_PMU_ADDR */ +3: + ldr w1, [x3, #PMU_CLAINACTSETR_OFFSET] + cbnz w1, 3b +4: + ldr w1, [x3, #PMU_CLSINACTSETR_OFFSET] + cbnz w1, 4b + + /* + * Enable the WakeRequest signal on cpu 0-1 + * x3 is cpu mask starting from cpu1 + */ + bl get_tot_num_cores + sub x0, x0, #1 + mov x3, #0x1 + lsl x3, x3, x0 +2: + mov x0, x3 + bl get_gic_rd_base // 0-2 + ldr w1, [x0, #GICR_WAKER_OFFSET] + bic w1, w1, #GICR_WAKER_SLEEP_BIT + str w1, [x0, #GICR_WAKER_OFFSET] +1: + ldr w1, [x0, #GICR_WAKER_OFFSET] + cbnz w1, 1b + + lsr x3, x3, #1 + cbnz x3, 2b + + /* Enable CCI snoop domain */ + ldr x0, =NXP_CCI_ADDR + str wzr, [x0] + dsb sy + isb + + ldr x3, =NXP_EPU_ADDR + + /* x3 = epu base addr */ + + /* Enable sec, enetc, spi and qspi */ + ldr x2, =NXP_DCFG_ADDR + str wzr, [x2, #DCFG_DEVDISR1_OFFSET] + str wzr, [x2, #DCFG_DEVDISR2_OFFSET] + str wzr, [x2, #DCFG_DEVDISR4_OFFSET] + + /* Restore flextimer/mmc/usb interrupt router */ + ldr x3, =NXP_GICD_ADDR + ldp x0, x2, [sp], #16 + ldr x1, =GICD_IROUTER113_OFFSET + str w2, [x3, x1] + ldr x1, =GICD_IROUTER112_OFFSET + str w0, [x3, x1] + ldp x0, x2, [sp], #16 + ldr x1, =GICD_IROUTER76_OFFSET + str w2, [x3, x1] + ldr x1, =GICD_IROUTER60_OFFSET + str w0, [x3, x1] + + /* Restore EPU registers */ + ldr x3, =NXP_EPU_ADDR + ldp x0, x2, [sp], #16 + str w2, [x3, #EPU_EPGCR_OFFSET] + str w0, [x3, #EPU_EPCTR10_OFFSET] + ldp x2, x1, [sp], #16 + str w1, [x3, #EPU_EPCCR10_OFFSET] + str w2, [x3, #EPU_EPIMCR10_OFFSET] + + dsb sy + isb + mov x30, x18 + ret + +/* + * Part of CPU_SUSPEND + * + * This function performs any SoC-specific cleanup after power-down + * in: x0 = core mask lsb + * out: none + * uses x0, x1 + */ +_soc_sys_exit_pwrdn: + /* Enable stack alignment checking */ + mrs x1, SCTLR_EL1 + orr x1, x1, #0x4 + msr SCTLR_EL1, x1 + + /* Enable debug interface */ + mrs x1, osdlr_el1 + bic x1, x1, #OSDLR_EL1_DLK_LOCK + msr osdlr_el1, x1 + + /* Enable i-cache */ + mrs x1, SCTLR_EL3 + orr x1, x1, #SCTLR_I_MASK + msr SCTLR_EL3, x1 + + isb + ret + +/* + * This function setc up the TrustZone Address Space Controller (TZASC) + * in: none + * out: none + * uses x0, x1 + */ +init_tzpc: + /* Set Non Secure access for all devices protected via TZPC */ + ldr x1, =TZPCDECPROT_0_SET_BASE /* decode Protection-0 Set Reg */ + mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ + str w0, [x1] + + ldr x1, =TZPCDECPROT_1_SET_BASE /* decode Protection-1 Set Reg */ + mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ + str w0, [x1] + + ldr x1, =TZPCDECPROT_2_SET_BASE /* decode Protection-2 Set Reg */ + mov w0, #0xFF /* set decode region to NS, Bits[7:0] */ + str w0, [x1] + + /* entire SRAM as NS */ + ldr x1, =NXP_OCRAM_TZPC_ADDR /* secure RAM region size Reg */ + mov w0, #0x00000000 /* 0x00000000 = no secure region */ + str w0, [x1] + + ret + +/* + * This function performs any needed initialization on SecMon for + * boot services + */ +initSecMon: + /* Read the register hpcomr */ + ldr x1, =NXP_SNVS_ADDR + ldr w0, [x1, #SECMON_HPCOMR_OFFSET] + /* Turn off secure access for the privileged registers */ + orr w0, w0, #SECMON_HPCOMR_NPSWAEN + /* Write back */ + str w0, [x1, #SECMON_HPCOMR_OFFSET] + + ret + +/* + * This function checks to see if cores which are to be disabled have been + * released from reset - if not, it releases them + * in: none + * out: none + * uses x0, x1, x2, x3, x4, x5, x6, x7, x8 + */ +release_disabled: + stp x18, x30, [sp, #-16]! + + /* + * Get the number of cpus on this device + * Calling the below c function. + * No need to Callee saved registers x9-x15, + * as these registers are not used by the callee + * prior to calling the below C-routine. + */ + bl get_tot_num_cores + mov x6, x0 + + /* Read COREDISABLESR */ + mov x0, #NXP_DCFG_ADDR + ldr w4, [x0, #DCFG_COREDISABLEDSR_OFFSET] + + mov x0, #NXP_RESET_ADDR + ldr w5, [x0, #BRR_OFFSET] + + /* Load the core mask for the first core */ + mov x7, #1 + + /* + * x4 = COREDISABLESR + * x5 = BRR + * x6 = loop count + * x7 = core mask bit + */ +2: + /* Check if the core is to be disabled */ + tst x4, x7 + b.eq 1f + + /* See if disabled cores have already been released from reset */ + tst x5, x7 + b.ne 1f + + /* If core has not been released, then release it (0-3) */ + mov x0, x7 + bl _soc_core_release + + /* Record the core state in the data area (0-3) */ + mov x0, x7 + mov x1, #CORE_DISABLED + bl _setCoreState +1: + /* Decrement the counter */ + subs x6, x6, #1 + b.le 3f + /* Shift the core mask to the next core */ + lsl x7, x7, #1 + /* Continue */ + b 2b +3: + ldp x18, x30, [sp], #16 + ret + +/* + * Write a register in the DCFG block + * in: x0 = offset + * in: w1 = value to write + * uses x0, x1, x2 + */ +_write_reg_dcfg: + ldr x2, =NXP_DCFG_ADDR + str w1, [x2, x0] + ret + +/* + * Read a register in the DCFG block + * in: x0 = offset + * out: w0 = value read + * uses x0, x1, x2 + */ +_read_reg_dcfg: + ldr x2, =NXP_DCFG_ADDR + ldr w1, [x2, x0] + mov w0, w1 + ret + +/* + * This function returns an mpidr value for a core, given a core_mask_lsb + * in: x0 = core mask lsb + * out: x0 = affinity2:affinity1:affinity0, where affinity is 8-bits + * uses x0, x1 + */ +get_mpidr_value: + /* Convert a core mask to an SoC core number */ + clz w0, w0 + mov w1, #31 + sub w0, w1, w0 + + /* Get the mpidr core number from the SoC core number */ + mov w1, wzr + tst x0, #1 + b.eq 1f + orr w1, w1, #1 +1: + /* Extract the cluster number */ + lsr w0, w0, #1 + orr w0, w1, w0, lsl #8 + + ret + +/* + * This function returns the redistributor base address for the core specified + * in x1 + * in: x0 - core mask lsb of specified core + * out: x0 = redistributor rd base address for specified core + * uses x0, x1, x2 + */ +get_gic_rd_base: + /* Get the 0-based core number */ + clz w1, w0 + mov w2, #0x20 + sub w2, w2, w1 + sub w2, w2, #1 + + /* x2 = core number / loop counter */ + ldr x0, =NXP_GICR_ADDR + mov x1, #GIC_RD_OFFSET +2: + cbz x2, 1f + add x0, x0, x1 + sub x2, x2, #1 + b 2b +1: + ret + +/* + * This function returns the redistributor base address for the core specified + * in x1 + * in: x0 - core mask lsb of specified core + * out: x0 = redistributor sgi base address for specified core + * uses x0, x1, x2 + */ +get_gic_sgi_base: + /* Get the 0-based core number */ + clz w1, w0 + mov w2, #0x20 + sub w2, w2, w1 + sub w2, w2, #1 + + /* x2 = core number / loop counter */ + ldr x0, =NXP_GICR_SGI_ADDR + mov x1, #GIC_SGI_OFFSET +2: + cbz x2, 1f + add x0, x0, x1 + sub x2, x2, #1 + b 2b +1: + ret + +/* + * Write a register in the RESET block + * in: x0 = offset + * in: w1 = value to write + * uses x0, x1, x2 + */ +_write_reg_reset: + ldr x2, =NXP_RESET_ADDR + str w1, [x2, x0] + ret + +/* + * Read a register in the RESET block + * in: x0 = offset + * out: w0 = value read + * uses x0, x1 + */ +_read_reg_reset: + ldr x1, =NXP_RESET_ADDR + ldr w0, [x1, x0] + ret diff --git a/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S new file mode 100644 index 000000000..ec67529eb --- /dev/null +++ b/plat/nxp/soc-ls1028a/aarch64/ls1028a_helpers.S @@ -0,0 +1,70 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +.globl plat_secondary_cold_boot_setup +.globl plat_is_my_cpu_primary +.globl plat_reset_handler +.globl platform_mem_init + +func platform_mem1_init + ret +endfunc platform_mem1_init + +func platform_mem_init + ret +endfunc platform_mem_init + +func apply_platform_errata + ret +endfunc apply_platform_errata + +func plat_reset_handler + mov x29, x30 + bl apply_platform_errata + +#if defined(IMAGE_BL31) + ldr x0, =POLICY_SMMU_PAGESZ_64K + cbz x0, 1f + /* Set the SMMU page size in the sACR register */ + bl _set_smmu_pagesz_64 +#endif +1: + mov x30, x29 + ret +endfunc plat_reset_handler + +/* + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + */ +func plat_secondary_cold_boot_setup + /* ls1028a does not do cold boot for secondary CPU */ +cb_panic: + b cb_panic +endfunc plat_secondary_cold_boot_setup + +/* + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, 0x0 + cset w0, eq + ret +endfunc plat_is_my_cpu_primary diff --git a/plat/nxp/soc-ls1028a/include/soc.h b/plat/nxp/soc-ls1028a/include/soc.h new file mode 100644 index 000000000..b1d044ad9 --- /dev/null +++ b/plat/nxp/soc-ls1028a/include/soc.h @@ -0,0 +1,149 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOC_H +#define SOC_H + +/* Chassis specific defines - common across SoC's of a particular platform */ +#include +#include +#include + +/* + * SVR Definition of LS1028A + * (not include major and minor rev) + * These info is listed in Table B-6. DCFG differences + * between LS1028A and LS1027A of LS1028ARM(Reference Manual) + */ +#define SVR_LS1017AN 0x870B25 +#define SVR_LS1017AE 0x870B24 +#define SVR_LS1018AN 0x870B21 +#define SVR_LS1018AE 0x870B20 +#define SVR_LS1027AN 0x870B05 +#define SVR_LS1027AE 0x870B04 +#define SVR_LS1028AN 0x870B01 +#define SVR_LS1028AE 0x870B00 + +/* Number of cores in platform */ +#define PLATFORM_CORE_COUNT 2 +#define NUMBER_OF_CLUSTERS 1 +#define CORES_PER_CLUSTER 2 + +/* Set to 0 if the clusters are not symmetrical */ +#define SYMMETRICAL_CLUSTERS 1 + +#define NUM_DRAM_REGIONS 3 + +#define NXP_DRAM0_ADDR 0x80000000 +#define NXP_DRAM0_MAX_SIZE 0x80000000 /* 2GB */ + +#define NXP_DRAM1_ADDR 0x2080000000 +#define NXP_DRAM1_MAX_SIZE 0x1F80000000 /* 126G */ + +#define NXP_DRAM2_ADDR 0x6000000000 +#define NXP_DRAM2_MAX_SIZE 0x2000000000 /* 128G */ + +/* DRAM0 Size defined in platform_def.h */ +#define NXP_DRAM0_SIZE PLAT_DEF_DRAM0_SIZE + +/* CCSR space memory Map */ +#undef NXP_UART_ADDR +#define NXP_UART_ADDR 0x021C0500 + +#undef NXP_UART1_ADDR +#define NXP_UART1_ADDR 0x021C0600 + +#undef NXP_WDOG1_TZ_ADDR +#define NXP_WDOG1_TZ_ADDR 0x023C0000 + +#undef NXP_GICR_ADDR +#define NXP_GICR_ADDR 0x06040000 + +#undef NXP_GICR_SGI_ADDR +#define NXP_GICR_SGI_ADDR 0x06050000 + +/* EPU register offsets and values */ +#define EPU_EPGCR_OFFSET 0x0 +#define EPU_EPIMCR10_OFFSET 0x128 +#define EPU_EPCTR10_OFFSET 0xa28 +#define EPU_EPCCR10_OFFSET 0x828 +#define EPU_EPCCR10_VAL 0xb2800000 +#define EPU_EPIMCR10_VAL 0xba000000 +#define EPU_EPCTR10_VAL 0x0 +#define EPU_EPGCR_VAL (1 << 31) + +/* PORSR1 */ +#define PORSR1_RCW_MASK 0x07800000 +#define PORSR1_RCW_SHIFT 23 + +#define SDHC1_VAL 0x8 +#define SDHC2_VAL 0x9 +#define I2C1_VAL 0xa +#define FLEXSPI_NAND2K_VAL 0xc +#define FLEXSPI_NAND4K_VAL 0xd +#define FLEXSPI_NOR 0xf + +/* + * Required LS standard platform porting definitions + * for CCI-400 + */ +#define NXP_CCI_CLUSTER0_SL_IFACE_IX 4 + +/* Defines required for using XLAT tables from ARM common code */ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 40) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 40) + +/* Clock Divisors */ +#define NXP_PLATFORM_CLK_DIVIDER 1 +#define NXP_UART_CLK_DIVIDER 2 + +/* dcfg register offsets and values */ +#define DCFG_DEVDISR2_ENETC (1 << 31) + +#define MPIDR_AFFINITY0_MASK 0x00FF +#define MPIDR_AFFINITY1_MASK 0xFF00 +#define CPUECTLR_DISABLE_TWALK_PREFETCH 0x4000000000 +#define CPUECTLR_INS_PREFETCH_MASK 0x1800000000 +#define CPUECTLR_DAT_PREFETCH_MASK 0x0300000000 +#define OSDLR_EL1_DLK_LOCK 0x1 +#define CNTP_CTL_EL0_EN 0x1 +#define CNTP_CTL_EL0_IMASK 0x2 + +#define SYSTEM_PWR_DOMAINS 1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ + NUMBER_OF_CLUSTERS + \ + SYSTEM_PWR_DOMAINS) + +/* Power state coordination occurs at the system level */ +#define PLAT_PD_COORD_LVL MPIDR_AFFLVL2 +#define PLAT_MAX_PWR_LVL PLAT_PD_COORD_LVL + +/* Local power state for power domains in Run state */ +#define LS_LOCAL_STATE_RUN PSCI_LOCAL_STATE_RUN + +/* define retention state */ +#define PLAT_MAX_RET_STATE (PSCI_LOCAL_STATE_RUN + 1) +#define LS_LOCAL_STATE_RET PLAT_MAX_RET_STATE + +/* define power-down state */ +#define PLAT_MAX_OFF_STATE (PLAT_MAX_RET_STATE + 1) +#define LS_LOCAL_STATE_OFF PLAT_MAX_OFF_STATE + +/* One cache line needed for bakery locks on ARM platforms */ +#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE) + +#ifndef __ASSEMBLER__ +/* CCI slave interfaces */ +static const int cci_map[] = { + NXP_CCI_CLUSTER0_SL_IFACE_IX, +}; +void soc_init_lowlevel(void); +void soc_init_percpu(void); +void _soc_set_start_addr(unsigned long addr); +void _set_platform_security(void); +#endif + +#endif /* SOC_H */ diff --git a/plat/nxp/soc-ls1028a/soc.c b/plat/nxp/soc-ls1028a/soc.c new file mode 100644 index 000000000..4f6715484 --- /dev/null +++ b/plat/nxp/soc-ls1028a/soc.c @@ -0,0 +1,420 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if TRUSTED_BOARD_BOOT +#include +#endif +#include +#ifdef CONFIG_OCRAM_ECC_EN +#include +#endif +#include +#include +#include +#include +#include +#if defined(NXP_SFP_ENABLED) +#include +#endif + +#include +#include "plat_common.h" +#include "platform_def.h" +#include "soc.h" + +static dcfg_init_info_t dcfg_init_data = { + .g_nxp_dcfg_addr = NXP_DCFG_ADDR, + .nxp_sysclk_freq = NXP_SYSCLK_FREQ, + .nxp_ddrclk_freq = NXP_DDRCLK_FREQ, + .nxp_plat_clk_divider = NXP_PLATFORM_CLK_DIVIDER, +}; + +static struct soc_type soc_list[] = { + SOC_ENTRY(LS1017AN, LS1017AN, 1, 1), + SOC_ENTRY(LS1017AE, LS1017AE, 1, 1), + SOC_ENTRY(LS1018AN, LS1018AN, 1, 1), + SOC_ENTRY(LS1018AE, LS1018AE, 1, 1), + SOC_ENTRY(LS1027AN, LS1027AN, 1, 2), + SOC_ENTRY(LS1027AE, LS1027AE, 1, 2), + SOC_ENTRY(LS1028AN, LS1028AN, 1, 2), + SOC_ENTRY(LS1028AE, LS1028AE, 1, 2), +}; + +CASSERT(NUMBER_OF_CLUSTERS && NUMBER_OF_CLUSTERS <= 256, + assert_invalid_ls1028a_cluster_count); + +/* + * Function returns the base counter frequency + * after reading the first entry at CNTFID0 (0x20 offset). + * + * Function is used by: + * 1. ARM common code for PSCI management. + * 2. ARM Generic Timer init. + * + */ +unsigned int plat_get_syscnt_freq2(void) +{ + unsigned int counter_base_frequency; + /* + * Below register specifies the base frequency of the system counter. + * As per NXP Board Manuals: + * The system counter always works with SYS_REF_CLK/4 frequency clock. + */ + counter_base_frequency = mmio_read_32(NXP_TIMER_ADDR + CNTFID_OFF); + + return counter_base_frequency; +} + +#ifdef IMAGE_BL2 +void soc_preload_setup(void) +{ +} + +void soc_early_init(void) +{ + uint8_t num_clusters, cores_per_cluster; + +#ifdef CONFIG_OCRAM_ECC_EN + ocram_init(NXP_OCRAM_ADDR, NXP_OCRAM_SIZE); +#endif + dcfg_init(&dcfg_init_data); + enable_timer_base_to_cluster(NXP_PMU_ADDR); + enable_core_tb(NXP_PMU_ADDR); + dram_regions_info_t *dram_regions_info = get_dram_regions_info(); + +#ifdef POLICY_FUSE_PROVISION + gpio_init(&gpio_init_data); + sec_init(NXP_CAAM_ADDR); +#endif + +#if LOG_LEVEL > 0 + /* Initialize the console to provide early debug support */ + plat_console_init(NXP_CONSOLE_ADDR, + NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); +#endif + enum boot_device dev = get_boot_dev(); + /* + * Mark the buffer for SD in OCRAM as non secure. + * The buffer is assumed to be at end of OCRAM for + * the logic below to calculate TZPC programming + */ + if (dev == BOOT_DEVICE_EMMC || dev == BOOT_DEVICE_SDHC2_EMMC) { + /* + * Calculate the region in OCRAM which is secure + * The buffer for SD needs to be marked non-secure + * to allow SD to do DMA operations on it + */ + uint32_t secure_region = (NXP_OCRAM_SIZE - NXP_SD_BLOCK_BUF_SIZE); + uint32_t mask = secure_region/TZPC_BLOCK_SIZE; + + mmio_write_32(NXP_OCRAM_TZPC_ADDR, mask); + + /* Add the entry for buffer in MMU Table */ + mmap_add_region(NXP_SD_BLOCK_BUF_ADDR, NXP_SD_BLOCK_BUF_ADDR, + NXP_SD_BLOCK_BUF_SIZE, MT_DEVICE | MT_RW | MT_NS); + } + +#if TRUSTED_BOARD_BOOT + uint32_t mode; + + sfp_init(NXP_SFP_ADDR); + + /* + * For secure boot disable SMMU. + * Later when platform security policy comes in picture, + * this might get modified based on the policy + */ + if (check_boot_mode_secure(&mode) == true) { + bypass_smmu(NXP_SMMU_ADDR); + } + + /* + * For Mbedtls currently crypto is not supported via CAAM + * enable it when that support is there. In tbbr.mk + * the CAAM_INTEG is set as 0. + */ +#ifndef MBEDTLS_X509 + /* Initialize the crypto accelerator if enabled */ + if (is_sec_enabled()) { + sec_init(NXP_CAAM_ADDR); + } else { + INFO("SEC is disabled.\n"); + } +#endif +#endif + + /* Set eDDRTQ for DDR performance */ + scfg_setbits32((void *)(NXP_SCFG_ADDR + 0x210), 0x1f1f1f1f); + + soc_errata(); + + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); + + /* + * Enable Interconnect coherency for the primary CPU's cluster. + */ + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + plat_ls_interconnect_enter_coherency(num_clusters); + + delay_timer_init(NXP_TIMER_ADDR); + i2c_init(NXP_I2C_ADDR); + dram_regions_info->total_dram_size = init_ddr(); +} + +void soc_bl2_prepare_exit(void) +{ +#if defined(NXP_SFP_ENABLED) && defined(DISABLE_FUSE_WRITE) + set_sfp_wr_disable(); +#endif +} + +/* + * This function returns the boot device based on RCW_SRC + */ +enum boot_device get_boot_dev(void) +{ + enum boot_device src = BOOT_DEVICE_NONE; + uint32_t porsr1; + uint32_t rcw_src; + + porsr1 = read_reg_porsr1(); + + rcw_src = (porsr1 & PORSR1_RCW_MASK) >> PORSR1_RCW_SHIFT; + switch (rcw_src) { + case FLEXSPI_NOR: + src = BOOT_DEVICE_FLEXSPI_NOR; + INFO("RCW BOOT SRC is FLEXSPI NOR\n"); + break; + case FLEXSPI_NAND2K_VAL: + case FLEXSPI_NAND4K_VAL: + INFO("RCW BOOT SRC is FLEXSPI NAND\n"); + src = BOOT_DEVICE_FLEXSPI_NAND; + break; + case SDHC1_VAL: + src = BOOT_DEVICE_EMMC; + INFO("RCW BOOT SRC is SD\n"); + break; + case SDHC2_VAL: + src = BOOT_DEVICE_SDHC2_EMMC; + INFO("RCW BOOT SRC is EMMC\n"); + break; + default: + break; + } + + return src; +} + +/* + * This function sets up access permissions on memory regions + ****************************************************************************/ +void soc_mem_access(void) +{ + dram_regions_info_t *info_dram_regions = get_dram_regions_info(); + struct tzc400_reg tzc400_reg_list[MAX_NUM_TZC_REGION]; + int dram_idx = 0; + /* index 0 is reserved for region-0 */ + int index = 1; + + for (dram_idx = 0; dram_idx < info_dram_regions->num_dram_regions; + dram_idx++) { + if (info_dram_regions->region[dram_idx].size == 0) { + ERROR("DDR init failure, or"); + ERROR("DRAM regions not populated correctly.\n"); + break; + } + + index = populate_tzc400_reg_list(tzc400_reg_list, + dram_idx, index, + info_dram_regions->region[dram_idx].addr, + info_dram_regions->region[dram_idx].size, + NXP_SECURE_DRAM_SIZE, NXP_SP_SHRD_DRAM_SIZE); + } + + mem_access_setup(NXP_TZC_ADDR, index, tzc400_reg_list); +} + +#else + +static unsigned char _power_domain_tree_desc[NUMBER_OF_CLUSTERS + 2]; +/* + * This function dynamically constructs the topology according to + * SoC Flavor and returns it. + */ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + uint8_t num_clusters, cores_per_cluster; + unsigned int i; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + /* + * The highest level is the system level. The next level is constituted + * by clusters and then cores in clusters. + */ + _power_domain_tree_desc[0] = 1; + _power_domain_tree_desc[1] = num_clusters; + + for (i = 0; i < _power_domain_tree_desc[1]; i++) + _power_domain_tree_desc[i + 2] = cores_per_cluster; + + return _power_domain_tree_desc; +} + +/* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + */ +unsigned int plat_ls_get_cluster_core_count(u_register_t mpidr) +{ + uint8_t num_clusters, cores_per_cluster; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + return num_clusters; +} + +void soc_early_platform_setup2(void) +{ + dcfg_init(&dcfg_init_data); + /* Initialize system level generic timer for Socs */ + delay_timer_init(NXP_TIMER_ADDR); + +#if LOG_LEVEL > 0 + /* Initialize the console to provide early debug support */ + plat_console_init(NXP_CONSOLE_ADDR, + NXP_UART_CLK_DIVIDER, NXP_CONSOLE_BAUDRATE); +#endif +} + +void soc_platform_setup(void) +{ + /* Initialize the GIC driver, cpu and distributor interfaces */ + static uintptr_t target_mask_array[PLATFORM_CORE_COUNT]; + static interrupt_prop_t ls_interrupt_props[] = { + PLAT_LS_G1S_IRQ_PROPS(INTR_GROUP1S), + PLAT_LS_G0_IRQ_PROPS(INTR_GROUP0) + }; + + plat_ls_gic_driver_init(NXP_GICD_ADDR, NXP_GICR_ADDR, + PLATFORM_CORE_COUNT, + ls_interrupt_props, + ARRAY_SIZE(ls_interrupt_props), + target_mask_array, + plat_core_pos); + + plat_ls_gic_init(); + enable_init_timer(); +} + +/* This function initializes the soc from the BL31 module */ +void soc_init(void) +{ + uint8_t num_clusters, cores_per_cluster; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + + /* Low-level init of the soc */ + soc_init_lowlevel(); + _init_global_data(); + soc_init_percpu(); + _initialize_psci(); + + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + cci_init(NXP_CCI_ADDR, cci_map, ARRAY_SIZE(cci_map)); + + /* Enable Interconnect coherency for the primary CPU's cluster. */ + plat_ls_interconnect_enter_coherency(num_clusters); + + /* Set platform security policies */ + _set_platform_security(); + + /* Init SEC Engine which will be used by SiP */ + if (is_sec_enabled()) { + sec_init(NXP_CAAM_ADDR); + } else { + INFO("SEC is disabled.\n"); + } +} + +#ifdef NXP_WDOG_RESTART +static uint64_t wdog_interrupt_handler(uint32_t id, uint32_t flags, + void *handle, void *cookie) +{ + uint8_t data = WDOG_RESET_FLAG; + + wr_nv_app_data(WDT_RESET_FLAG_OFFSET, + (uint8_t *)&data, sizeof(data)); + + mmio_write_32(NXP_RST_ADDR + RSTCNTL_OFFSET, SW_RST_REQ_INIT); + + return 0; +} +#endif + +void soc_runtime_setup(void) +{ +#ifdef NXP_WDOG_RESTART + request_intr_type_el3(BL31_NS_WDOG_WS1, wdog_interrupt_handler); +#endif +} + +/* This function returns the total number of cores in the SoC. */ +unsigned int get_tot_num_cores(void) +{ + uint8_t num_clusters, cores_per_cluster; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + return (num_clusters * cores_per_cluster); +} + +/* This function returns the PMU IDLE Cluster mask. */ +unsigned int get_pmu_idle_cluster_mask(void) +{ + uint8_t num_clusters, cores_per_cluster; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + return ((1 << num_clusters) - 2); +} + +/* This function returns the PMU Flush Cluster mask. */ +unsigned int get_pmu_flush_cluster_mask(void) +{ + uint8_t num_clusters, cores_per_cluster; + + get_cluster_info(soc_list, ARRAY_SIZE(soc_list), &num_clusters, &cores_per_cluster); + return ((1 << num_clusters) - 2); +} + +/* This function returns the PMU idle core mask. */ +unsigned int get_pmu_idle_core_mask(void) +{ + return ((1 << get_tot_num_cores()) - 2); +} + +/* Function to return the SoC SYS CLK */ +unsigned int get_sys_clk(void) +{ + return NXP_SYSCLK_FREQ; +} +#endif diff --git a/plat/nxp/soc-ls1028a/soc.def b/plat/nxp/soc-ls1028a/soc.def new file mode 100644 index 000000000..e13398289 --- /dev/null +++ b/plat/nxp/soc-ls1028a/soc.def @@ -0,0 +1,95 @@ +# +# Copyright 2018-2021 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# +# +#------------------------------------------------------------------------------ +# +# This file contains the basic architecture definitions that drive the build +# +# ----------------------------------------------------------------------------- + +CORE_TYPE := a72 + +CACHE_LINE := 6 + +# Set to GIC400 or GIC500 +GIC := GIC500 + +# Set to CCI400 or CCN504 or CCN508 +INTERCONNECT := CCI400 + +# Layerscape chassis level - set to 3=LSCH3 or 2=LSCH2 +CHASSIS := 3_2 + +# TZC used is TZC380 or TZC400 +TZC_ID := TZC400 + +# CONSOLE is NS16550 or PL011 +CONSOLE := NS16550 + +# DDR PHY generation to be used +PLAT_DDR_PHY := PHY_GEN1 + +PHYS_SYS := 64 + +# Max Size of CSF header. Required to define BL2 TEXT LIMIT in soc.def +# Input to CST create_hdr_esbc tool +CSF_HDR_SZ := 0x3000 + +# In IMAGE_BL2, compile time flag for handling Cache coherency +# with CAAM for BL2 running from OCRAM +SEC_MEM_NON_COHERENT := yes + +# OCRAM MAP for BL2 +# Before BL2 +# 0x18000000 - 0x18009fff -> Used by ROM code +# 0x1800a000 - 0x1800dfff -> CSF header for BL2 +# For FlexSFlexSPI boot +# 0x1800e000 - 0x18040000 -> Reserved for BL2 binary +# For SD boot +# 0x1800e000 - 0x18030000 -> Reserved for BL2 binary +# 0x18030000 - 0x18040000 -> Reserved for SD buffer +OCRAM_START_ADDR := 0x18000000 +OCRAM_SIZE := 0x40000 + +# Area of OCRAM reserved by ROM code +NXP_ROM_RSVD := 0xa000 + +# Location of BL2 on OCRAM +BL2_BASE_ADDR := $(shell echo $$(( $(OCRAM_START_ADDR) + $(NXP_ROM_RSVD) + $(CSF_HDR_SZ) ))) + +# Covert to HEX to be used by create_pbl.mk +BL2_BASE := $(shell echo "0x"$$(echo "obase=16; ${BL2_BASE_ADDR}" | bc)) + +# BL2_HDR_LOC is at (BL2_BASE + NXP_ROM_RSVD) +# This value BL2_HDR_LOC + CSF_HDR_SZ should not +# overalp with BL2_BASE +# Input to CST create_hdr_isbc tool +BL2_HDR_LOC := 0x1800A000 + +# SoC ERRATAS to be enabled +ERRATA_SOC_A008850 := 1 + +ERRATA_DDR_A009803 := 1 +ERRATA_DDR_A009942 := 1 +ERRATA_DDR_A010165 := 1 + +# Enable dynamic memory mapping +PLAT_XLAT_TABLES_DYNAMIC := 1 + +# Define Endianness of each module +NXP_GUR_ENDIANNESS := LE +NXP_DDR_ENDIANNESS := LE +NXP_SEC_ENDIANNESS := LE +NXP_SFP_ENDIANNESS := LE +NXP_SNVS_ENDIANNESS := LE +NXP_ESDHC_ENDIANNESS := LE +NXP_QSPI_ENDIANNESS := LE +NXP_FSPI_ENDIANNESS := LE + +NXP_SFP_VER := 3_4 + +# OCRAM ECC Enabled +OCRAM_ECC_EN := yes diff --git a/plat/nxp/soc-ls1028a/soc.mk b/plat/nxp/soc-ls1028a/soc.mk new file mode 100644 index 000000000..92d8e9819 --- /dev/null +++ b/plat/nxp/soc-ls1028a/soc.mk @@ -0,0 +1,113 @@ +# +# Copyright 2020-2021 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# SoC-specific build parameters +SOC := ls1028a +PLAT_PATH := plat/nxp +PLAT_COMMON_PATH := plat/nxp/common +PLAT_DRIVERS_PATH := drivers/nxp +PLAT_SOC_PATH := ${PLAT_PATH}/soc-${SOC} +BOARD_PATH := ${PLAT_SOC_PATH}/${BOARD} + +# Get SoC-specific definitions +include ${PLAT_SOC_PATH}/soc.def +include ${PLAT_COMMON_PATH}/plat_make_helper/soc_common_def.mk +include ${PLAT_COMMON_PATH}/plat_make_helper/plat_build_macros.mk + +ifeq (${TRUSTED_BOARD_BOOT},1) +$(eval $(call SET_NXP_MAKE_FLAG,SMMU_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,SNVS_NEEDED,BL2)) +SECURE_BOOT := yes +endif +$(eval $(call SET_NXP_MAKE_FLAG,CRYPTO_NEEDED,BL_COMM)) + +$(eval $(call SET_NXP_MAKE_FLAG,DCFG_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,TIMER_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,INTERCONNECT_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,GIC_NEEDED,BL31)) +$(eval $(call SET_NXP_MAKE_FLAG,CONSOLE_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,PMU_NEEDED,BL_COMM)) +$(eval $(call SET_NXP_MAKE_FLAG,DDR_DRIVER_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,TZASC_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,I2C_NEEDED,BL2)) +$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2)) + +# Selecting PSCI & SIP_SVC support +$(eval $(call SET_NXP_MAKE_FLAG,PSCI_NEEDED,BL31)) +$(eval $(call SET_NXP_MAKE_FLAG,SIPSVC_NEEDED,BL31)) + +PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/include/default\ + -I${BOARD_PATH}\ + -I${PLAT_COMMON_PATH}/include/default/ch_${CHASSIS}\ + -I${PLAT_SOC_PATH}/include\ + -I${PLAT_COMMON_PATH}/soc_errata + +ifeq (${SECURE_BOOT},yes) +include ${PLAT_COMMON_PATH}/tbbr/tbbr.mk +endif + +ifeq ($(WARM_BOOT),yes) +include ${PLAT_COMMON_PATH}/warm_reset/warm_reset.mk +endif + +ifeq (${NXP_NV_SW_MAINT_LAST_EXEC_DATA}, yes) +include ${PLAT_COMMON_PATH}/nv_storage/nv_storage.mk +endif + +ifeq (${PSCI_NEEDED}, yes) +include ${PLAT_COMMON_PATH}/psci/psci.mk +endif + +ifeq (${SIPSVC_NEEDED}, yes) +include ${PLAT_COMMON_PATH}/sip_svc/sipsvc.mk +endif + +ifeq (${DDR_FIP_IO_NEEDED}, yes) +include ${PLAT_COMMON_PATH}/fip_handler/ddr_fip/ddr_fip_io.mk +endif + +# For fuse-fip & fuse-programming +ifeq (${FUSE_PROG}, 1) +include ${PLAT_COMMON_PATH}/fip_handler/fuse_fip/fuse.mk +endif + +ifeq (${IMG_LOADR_NEEDED},yes) +include $(PLAT_COMMON_PATH)/img_loadr/img_loadr.mk +endif + +# Adding source files for the above selected drivers. +include ${PLAT_DRIVERS_PATH}/drivers.mk + +# Adding SoC specific files +include ${PLAT_COMMON_PATH}/soc_errata/errata.mk + +PLAT_INCLUDES += ${NV_STORAGE_INCLUDES}\ + ${WARM_RST_INCLUDES} + +BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/${SOC}.S\ + ${WARM_RST_BL31_SOURCES}\ + ${PSCI_SOURCES}\ + ${SIPSVC_SOURCES}\ + ${PLAT_COMMON_PATH}/$(ARCH)/bl31_data.S + +PLAT_BL_COMMON_SOURCES += ${PLAT_COMMON_PATH}/$(ARCH)/ls_helpers.S\ + ${PLAT_SOC_PATH}/aarch64/${SOC}_helpers.S\ + ${NV_STORAGE_SOURCES}\ + ${WARM_RST_BL_COMM_SOURCES}\ + ${PLAT_SOC_PATH}/soc.c + +ifeq (${TEST_BL31}, 1) +BL31_SOURCES += ${PLAT_SOC_PATH}/$(ARCH)/bootmain64.S \ + ${PLAT_SOC_PATH}/$(ARCH)/nonboot64.S +endif + +BL2_SOURCES += ${DDR_CNTLR_SOURCES}\ + ${TBBR_SOURCES}\ + ${FUSE_SOURCES} + +# Adding TFA setup files +include ${PLAT_PATH}/common/setup/common.mk -- cgit v1.2.3 From 34e2112d1a3a8e4ea33a24bdc6505518266333a9 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 13 Sep 2021 16:12:28 +0800 Subject: feat(plat/nxp/ls1028ardb): add ls1028ardb board support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The LS1028A reference design board (RDB) is a computing, evaluation, and development platform that supports industrial IoT applications, human machine interface solutions, and industrial networking. It supports the following features: 1. Layerscape LS1028A dual-core processor based on Cortex-A72 at 1.3 GHz. 2. 4 GB DDR4 SDRAM w/ECC 3. Support Ethernet: 1) x1 RJ45 connector for 1Gbps Ethernet support w/TSN, 1588 2) x4 RJ45 connector for 1Gbps Ethernet switch support w/TSN, 1588 (QSGMII) 3. With Basic Peripherals and Interconnect 2x M.2 Type E slots with PCIe Gen 3.0 x1 1x M.2 Type B slot with SATA 3.0 (resistor mux with 1 Type E slot) 1x Type A USB 3.0 super-speed port 1x Type C USB 3.0 super-speed port 1x DisplayPort interface 2x DB9 RS232 serial ports 2x DB9 CAN interfaces 1x 3.5 mm audio out 2x MikroBUS™ sockets Signed-off-by: Ruchika Gupta Signed-off-by: York Sun Signed-off-by: Pankaj Gupta Signed-off-by: Jiafei Pan Signed-off-by: Yangbo Lu Change-Id: I48ee254a488ae4af227641da3875a1e9a63a720c --- plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c | 185 +++++++++++++++++++++++++ plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h | 76 ++++++++++ plat/nxp/soc-ls1028a/ls1028ardb/platform.c | 28 ++++ plat/nxp/soc-ls1028a/ls1028ardb/platform.mk | 33 +++++ plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h | 13 ++ plat/nxp/soc-ls1028a/ls1028ardb/policy.h | 16 +++ 6 files changed, 351 insertions(+) create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/platform.c create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/platform.mk create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h create mode 100644 plat/nxp/soc-ls1028a/ls1028ardb/policy.h diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c new file mode 100644 index 000000000..d82be51c8 --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/ddr_init.c @@ -0,0 +1,185 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include + +#include +#include +#include + +#include + +#ifdef CONFIG_STATIC_DDR +const struct ddr_cfg_regs static_1600 = { + .cs[0].config = U(0x80040422), + .cs[0].bnds = U(0xFF), + .sdram_cfg[0] = U(0xE50C0004), + .sdram_cfg[1] = U(0x401100), + .timing_cfg[0] = U(0x91550018), + .timing_cfg[1] = U(0xBAB40C42), + .timing_cfg[2] = U(0x48C111), + .timing_cfg[3] = U(0x1111000), + .timing_cfg[4] = U(0x2), + .timing_cfg[5] = U(0x3401400), + .timing_cfg[7] = U(0x23300000), + .timing_cfg[8] = U(0x2114600), + .sdram_mode[0] = U(0x3010210), + .sdram_mode[9] = U(0x4000000), + .sdram_mode[8] = U(0x500), + .sdram_mode[2] = U(0x10210), + .sdram_mode[10] = U(0x400), + .sdram_mode[11] = U(0x4000000), + .sdram_mode[4] = U(0x10210), + .sdram_mode[12] = U(0x400), + .sdram_mode[13] = U(0x4000000), + .sdram_mode[6] = U(0x10210), + .sdram_mode[14] = U(0x400), + .sdram_mode[15] = U(0x4000000), + .interval = U(0x18600618), + .data_init = U(0xdeadbeef), + .zq_cntl = U(0x8A090705), + .clk_cntl = U(0x2000000), + .cdr[0] = U(0x80040000), + .cdr[1] = U(0xA181), + .wrlvl_cntl[0] = U(0x8675F605), + .wrlvl_cntl[1] = U(0x6070700), + .wrlvl_cntl[2] = U(0x0000008), + .dq_map[0] = U(0x5b65b658), + .dq_map[1] = U(0xd96d8000), + .dq_map[2] = U(0), + .dq_map[3] = U(0x1600000), + .debug[28] = U(0x00700046), +}; + +unsigned long long board_static_ddr(struct ddr_info *priv) +{ + memcpy(&priv->ddr_reg, &static_1600, sizeof(static_1600)); + return ULL(0x100000000); +} + +#else + +static const struct rc_timing rcz[] = { + {1600, 8, 5}, + {} +}; + +static const struct board_timing ram[] = { + {0x1f, rcz, 0x1020200, 0x00000003}, +}; + +int ddr_board_options(struct ddr_info *priv) +{ + int ret; + struct memctl_opt *popts = &priv->opt; + + ret = cal_board_params(priv, ram, ARRAY_SIZE(ram)); + if (ret != 0) { + return ret; + } + + popts->bstopre = U(0x40); /* precharge value */ + popts->half_strength_drive_en = 1; + popts->cpo_sample = U(0x46); + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | + DDR_CDR1_ODT(DDR_CDR_ODT_80ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) | + DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */ + + popts->addr_hash = 1; /* address hashing */ + return 0; +} + +/* DDR model number: MT40A1G8SA-075:E */ +struct dimm_params ddr_raw_timing = { + .n_ranks = U(1), + .rank_density = ULL(4294967296), + .capacity = ULL(4294967296), + .primary_sdram_width = U(32), + .ec_sdram_width = U(4), + .rdimm = U(0), + .mirrored_dimm = U(0), + .n_row_addr = U(16), + .n_col_addr = U(10), + .bank_group_bits = U(2), + .edc_config = U(2), + .burst_lengths_bitmask = U(0x0c), + .tckmin_x_ps = 750, + .tckmax_ps = 1900, + .caslat_x = U(0x0001FFE00), + .taa_ps = 13500, + .trcd_ps = 13500, + .trp_ps = 13500, + .tras_ps = 32000, + .trc_ps = 45500, + .twr_ps = 15000, + .trfc1_ps = 350000, + .trfc2_ps = 260000, + .trfc4_ps = 160000, + .tfaw_ps = 21000, + .trrds_ps = 3000, + .trrdl_ps = 4900, + .tccdl_ps = 5000, + .refresh_rate_ps = U(7800000), + .dq_mapping[0] = U(0x16), + .dq_mapping[1] = U(0x36), + .dq_mapping[2] = U(0x16), + .dq_mapping[3] = U(0x36), + .dq_mapping[4] = U(0x16), + .dq_mapping[5] = U(0x36), + .dq_mapping[6] = U(0x16), + .dq_mapping[7] = U(0x36), + .dq_mapping[8] = U(0x16), + .dq_mapping[9] = U(0x0), + .dq_mapping[10] = U(0x0), + .dq_mapping[11] = U(0x0), + .dq_mapping[12] = U(0x0), + .dq_mapping[13] = U(0x0), + .dq_mapping[14] = U(0x0), + .dq_mapping[15] = U(0x0), + .dq_mapping[16] = U(0x0), + .dq_mapping[17] = U(0x0), + .dq_mapping_ors = U(0), + .rc = U(0x1f), +}; + +int ddr_get_ddr_params(struct dimm_params *pdimm, + struct ddr_conf *conf) +{ + static const char dimm_model[] = "Fixed DDR on board"; + + conf->dimm_in_use[0] = 1; + memcpy(pdimm, &ddr_raw_timing, sizeof(struct dimm_params)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + + return 1; +} +#endif + +int64_t init_ddr(void) +{ + struct ddr_info info; + struct sysinfo sys; + int64_t dram_size; + + zeromem(&sys, sizeof(sys)); + get_clocks(&sys); + debug("platform clock %lu\n", sys.freq_platform); + debug("DDR PLL1 %lu\n", sys.freq_ddr_pll0); + + zeromem(&info, sizeof(struct ddr_info)); + info.num_ctlrs = 1; + info.dimm_on_ctlr = 1; + info.clk = get_ddr_freq(&sys, 0); + info.ddr[0] = (void *)NXP_DDR_ADDR; + + dram_size = dram_init(&info); + + if (dram_size < 0) { + ERROR("DDR init failed.\n"); + } + + return dram_size; +} diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h new file mode 100644 index 000000000..63c0219d1 --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/plat_def.h @@ -0,0 +1,76 @@ +/* + * Copyright 2018-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DEF_H +#define PLAT_DEF_H + +#include +#include +/* + * Required without TBBR. + * To include the defines for DDR PHY + * Images. + */ +#include + +#include +#include + + +#define NXP_SYSCLK_FREQ 100000000 +#define NXP_DDRCLK_FREQ 100000000 + +/* UART related definition */ +#define NXP_CONSOLE_ADDR NXP_UART_ADDR +#define NXP_CONSOLE_BAUDRATE 115200 + +#define NXP_SPD_EEPROM0 0x51 + +/* Size of cacheable stacks */ +#if defined(IMAGE_BL2) +#if defined(TRUSTED_BOARD_BOOT) +#define PLATFORM_STACK_SIZE 0x2000 +#else +#define PLATFORM_STACK_SIZE 0x1000 +#endif +#elif defined(IMAGE_BL31) +#define PLATFORM_STACK_SIZE 0x1000 +#endif + +/* SD block buffer */ +#define NXP_SD_BLOCK_BUF_SIZE (0xC000) + +#ifdef SD_BOOT +#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE \ + - NXP_SD_BLOCK_BUF_SIZE) +#else +#define BL2_LIMIT (NXP_OCRAM_ADDR + NXP_OCRAM_SIZE) +#endif +#define BL2_TEXT_LIMIT (BL2_LIMIT) + +/* IO defines as needed by IO driver framework */ +#define MAX_IO_DEVICES 4 +#define MAX_IO_BLOCK_DEVICES 1 +#define MAX_IO_HANDLES 4 + +#define BL31_WDOG_SEC 89 + +/* + * Define properties of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_LS_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BL32_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE) + +/* SGI 15 and Secure watchdog interrupts assigned to Group 0 */ +#define PLAT_LS_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(BL31_WDOG_SEC, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(15, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) +#endif /* PLAT_DEF_H */ diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.c b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c new file mode 100644 index 000000000..65d508c97 --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.c @@ -0,0 +1,28 @@ +/* + * Copyright 2020-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#pragma weak board_enable_povdd +#pragma weak board_disable_povdd + +bool board_enable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} + +bool board_disable_povdd(void) +{ +#ifdef CONFIG_POVDD_ENABLE + return true; +#else + return false; +#endif +} diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk new file mode 100644 index 000000000..c4550006e --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform.mk @@ -0,0 +1,33 @@ +# +# Copyright 2020-2021 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Board-specific build parameters +BOOT_MODE ?= flexspi_nor +BOARD := ls1028ardb +POVDD_ENABLE := no +WARM_BOOT := no + +# DDR build parameters +NUM_OF_DDRC := 1 +CONFIG_DDR_NODIMM := 1 +DDR_ECC_EN := yes + +# On-board flash +FLASH_TYPE := MT35XU02G +XSPI_FLASH_SZ := 0x10000000 + +BL2_SOURCES += ${BOARD_PATH}/ddr_init.c \ + ${BOARD_PATH}/platform.c + +SUPPORTED_BOOT_MODE := flexspi_nor \ + sd \ + emmc + +# Add platform board build info +include plat/nxp/common/plat_make_helper/plat_common_def.mk + +# Add SoC build info +include plat/nxp/soc-ls1028a/soc.mk diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h new file mode 100644 index 000000000..bbad293ae --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/platform_def.h @@ -0,0 +1,13 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/nxp/soc-ls1028a/ls1028ardb/policy.h b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h new file mode 100644 index 000000000..67a8b4502 --- /dev/null +++ b/plat/nxp/soc-ls1028a/ls1028ardb/policy.h @@ -0,0 +1,16 @@ +/* + * Copyright 2020-2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef POLICY_H +#define POLICY_H + +/* + * Set this to 0x0 to leave the default SMMU page size in sACR + * Set this to 0x1 to change the SMMU page size to 64K + */ +#define POLICY_SMMU_PAGESZ_64K 0x1 + +#endif /* POLICY_H */ -- cgit v1.2.3 From 52a1e9ff37251987b71b743951038cd8d1fa0ba4 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Wed, 15 Sep 2021 11:12:50 +0800 Subject: feat(docs/nxp/layerscape): add ls1028a soc and board support Update nxp-layerscape to add ls1028a SoC and ls1028ardb board support. Signed-off-by: Jiafei Pan Change-Id: I9c7cc586f3718b488a6757994d65f6df69e7e165 --- docs/plat/nxp/nxp-layerscape.rst | 89 +++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 10 deletions(-) diff --git a/docs/plat/nxp/nxp-layerscape.rst b/docs/plat/nxp/nxp-layerscape.rst index 3d983542f..9a470e63d 100644 --- a/docs/plat/nxp/nxp-layerscape.rst +++ b/docs/plat/nxp/nxp-layerscape.rst @@ -5,22 +5,62 @@ NXP SoCs - Overview The QorIQ family of ARM based SoCs that are supported on TF-A are: -1. LX2160ARDB: - Platform Name: +1. LX2160A - a. lx2160ardb (Board details can be fetched from the link: `lx2160ardb`_) +- SoC Overview: +The LX2160A multicore processor, the highest-performance member of the +Layerscape family, combines FinFET process technology's low power and +sixteen Arm® Cortex®-A72 cores with datapath acceleration optimized for +L2/3 packet processing, together with security offload, robust traffic +management and quality of service. + +Details about LX2160A can be found at `lx2160a`_. + +- LX2160ARDB Board: + +The LX2160A reference design board provides a comprehensive platform +that enables design and evaluation of the LX2160A or LX2162A processors. It +comes preloaded with a board support package (BSP) based on a standard Linux +kernel. + +Board details can be fetched from the link: `lx2160ardb`_. + +2. LS1028A + +- SoC Overview: + +The Layerscape LS1028A applications processor for industrial and +automotive includes a time-sensitive networking (TSN) -enabled Ethernet +switch and Ethernet controllers to support converged IT and OT networks. +Two powerful 64-bit Arm®v8 cores support real-time processing for +industrial control and virtual machines for edge computing in the IoT. +The integrated GPU and LCD controller enable Human-Machine Interface +(HMI) systems with next-generation interfaces. + +Details about LS1028A can be found at `ls1028a`_. + +- LS1028ARDB Boards: + +The LS1028A reference design board (RDB) is a computing, evaluation, +and development platform that supports industrial IoT applications, human +machine interface solutions, and industrial networking. + +Details about LS1028A RDB board can be found at `ls1028ardb`_. Table of supported boot-modes by each platform & platform that needs FIP-DDR: ----------------------------------------------------------------------------- -+---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ -| | BOOT_MODE-->| sd | qspi | nor | nand | emmc | flexspi_nor | flexspi_nand | fip_ddr needed | -| | | | | | | | | | | -| | PLAT | | | | | | | | | -+===+=================+=======+========+=======+=======+=======+=============+==============+=================+ -| 1.| lx2160ardb | yes | | | | yes | yes | | yes | -+---+-----------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ ++---------------------+---------------------------------------------------------------------+-----------------+ +| | BOOT_MODE | | +| PLAT +-------+--------+-------+-------+-------+-------------+--------------+ fip_ddr_needed | +| | sd | qspi | nor | nand | emmc | flexspi_nor | flexspi_nand | | ++=====================+=======+========+=======+=======+=======+=============+==============+=================+ +| lx2160ardb | yes | | | | yes | yes | | yes | ++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ +| ls1028ardb | yes | | | | yes | yes | | no | ++---------------------+-------+--------+-------+-------+-------+-------------+--------------+-----------------+ + Boot Sequence ------------- @@ -54,6 +94,32 @@ Boot Sequence with FIP-DDR + EL3 BootROM --> BL2 -----> BL31 ---------------/ + +DDR Memory Layout +-------------------------- + +NXP Platforms divide DRAM into banks: + +- DRAM0 Bank: Maximum size of this bank is fixed to 2GB, DRAM0 size is defined in platform_def.h if it is less than 2GB. + +- DRAM1 ~ DRAMn Bank: Greater than 2GB belongs to DRAM1 and following banks, and size of DRAMn Bank varies for one platform to others. + +The following diagram is default DRAM0 memory layout in which secure memory is at top of DRAM0. + +:: + + high +---------------------------------------------+ + | | + | Secure EL1 Payload Shared Memory (2 MB) | + | | + +---------------------------------------------+ + | | + | Secure Memory (64 MB) | + | | + +---------------------------------------------+ + | | + | Non Secure Memory | + | | + low +---------------------------------------------+ How to build ============= @@ -228,5 +294,8 @@ For TBBR, the binary name changes: Refer `nxp-ls-tbbr.rst`_ for detailed user steps. +.. _lx2160a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-lx2160a-lx2120a-lx2080a-processors:LX2160A .. _lx2160ardb: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-communication-process/layerscape-lx2160a-multicore-communications-processor:LX2160A +.. _ls1028a: https://www.nxp.com/products/processors-and-microcontrollers/arm-processors/layerscape-processors/layerscape-1028a-applications-processor:LS1028A +.. _ls1028ardb: https://www.nxp.com/design/qoriq-developer-resources/layerscape-ls1028a-reference-design-board:LS1028ARDB .. _nxp-ls-tbbr.rst: ./nxp-ls-tbbr.rst -- cgit v1.2.3 From fc299ce07bd32d8c5376fdaa67b5e8b0201f222c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 23 Sep 2021 12:33:42 +0200 Subject: refactor(drivers/marvell/comphy-3700): simplify usage of sata power off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function mvebu_a3700_comphy_sata_power_off() uses comphy_mode parameter only for extracting mode bits. Mode is always COMPHY_SATA_MODE, so there is no need to pass comphy_mode parameter to this function. Use directly COMPHY_SATA_MODE in mvebu_a3700_comphy_sata_power_off(). Signed-off-by: Pali Rohár Change-Id: Ib6b7c2bf62c1ef4d8a6af240c08696d5cd506b14 --- drivers/marvell/comphy/phy-comphy-3700.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 027d07d17..6a0e44141 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -919,10 +919,9 @@ static int mvebu_a3700_comphy_usb3_power_off(void) return 0; } -static int mvebu_a3700_comphy_sata_power_off(uint32_t comphy_mode) +static int mvebu_a3700_comphy_sata_power_off(void) { uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG; - int mode = COMPHY_GET_MODE(comphy_mode); uint32_t offset; debug_enter(); @@ -930,12 +929,12 @@ static int mvebu_a3700_comphy_sata_power_off(uint32_t comphy_mode) /* Set phy isolation mode */ offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET; comphy_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE, - PHY_ISOLATE_MODE, mode); + PHY_ISOLATE_MODE, COMPHY_SATA_MODE); /* Power off PLL, Tx, Rx */ offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET; comphy_set_indirect(comphy_indir_regs, offset, 0, - PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT, mode); + PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT, COMPHY_SATA_MODE); debug_exit(); @@ -968,7 +967,7 @@ int mvebu_3700_comphy_power_off(uint8_t comphy_index, uint32_t comphy_mode) err = mvebu_a3700_comphy_usb3_power_off(); break; case (COMPHY_SATA_MODE): - err = mvebu_a3700_comphy_sata_power_off(comphy_mode); + err = mvebu_a3700_comphy_sata_power_off(); break; default: -- cgit v1.2.3 From 95fe195d53c8f6e83f3b88594ac4bc5952f4634e Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Thu, 16 Sep 2021 15:27:53 -0700 Subject: errata: workaround for Cortex-A710 erratum 2083908 Cortex-A710 erratum 2083908 is a Cat B erratum that applies to revision r2p0 and is still open. The workaround is to set CPUACTLR5_EL1[13] to 1. SDEN can be found here: https://developer.arm.com/documentation/SDEN1775101/latest Signed-off-by: nayanpatel-arm Change-Id: I876d26a7ac6ab0d7c567a9ec9f34fc0f952589d8 --- docs/design/cpu-specific-build-macros.rst | 4 ++++ include/lib/cpus/aarch64/cortex_a710.h | 10 ++++++-- lib/cpus/aarch64/cortex_a710.S | 38 +++++++++++++++++++++++++++++-- lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index bde6d97e6..80e7821f7 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -389,6 +389,10 @@ For Cortex-A710, the following errata build flags are defined : Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 of the CPU and is still open. +- ``ERRATA_A710_2083908``: This applies errata 2083908 workaround to + Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU and + is still open. + For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2 diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h index 8b011aaea..19394ba10 100644 --- a/include/lib/cpus/aarch64/cortex_a710.h +++ b/include/lib/cpus/aarch64/cortex_a710.h @@ -13,7 +13,7 @@ * CPU Extended Control register specific definitions ******************************************************************************/ #define CORTEX_A710_CPUECTLR_EL1 S3_0_C15_C1_4 -#define CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8) +#define CORTEX_A710_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8) /******************************************************************************* * CPU Power Control register specific definitions @@ -25,6 +25,12 @@ * CPU Auxiliary Control register specific definitions. ******************************************************************************/ #define CORTEX_A710_CPUACTLR_EL1 S3_0_C15_C1_0 -#define CORTEX_A710_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) +#define CORTEX_A710_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) + +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define CORTEX_A710_CPUACTLR5_EL1 S3_0_C15_C8_0 +#define CORTEX_A710_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13) #endif /* CORTEX_A710_H */ diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S index 75b7647bd..f6a4209c4 100644 --- a/lib/cpus/aarch64/cortex_a710.S +++ b/lib/cpus/aarch64/cortex_a710.S @@ -160,6 +160,34 @@ func check_errata_2017096 b cpu_rev_var_ls endfunc check_errata_2017096 + +/* --------------------------------------------------------------------- + * Errata Workaround for Cortex-A710 Erratum 2083908. + * This applies to revision r2p0 of Cortex-A710 and is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * --------------------------------------------------------------------- + */ +func errata_a710_2083908_wa + /* Compare x0 against revision r2p0 */ + mov x17, x30 + bl check_errata_2083908 + cbz x0, 1f + mrs x1, CORTEX_A710_CPUACTLR5_EL1 + orr x1, x1, CORTEX_A710_CPUACTLR5_EL1_BIT_13 + msr CORTEX_A710_CPUACTLR5_EL1, x1 +1: + ret x17 +endfunc errata_a710_2083908_wa + +func check_errata_2083908 + /* Applies to r2p0 */ + mov x1, #CPU_REV(2, 0) + mov x2, #CPU_REV(2, 0) + b cpu_rev_var_range +endfunc check_errata_2083908 + /* ---------------------------------------------------- * HW will do the cache maintenance while powering down * ---------------------------------------------------- @@ -194,6 +222,7 @@ func cortex_a710_errata_report report_errata ERRATA_A710_2081180, cortex_a710, 2081180 report_errata ERRATA_A710_2055002, cortex_a710, 2055002 report_errata ERRATA_A710_2017096, cortex_a710, 2017096 + report_errata ERRATA_A710_2083908, cortex_a710, 2083908 ldp x8, x30, [sp], #16 ret @@ -225,8 +254,13 @@ func cortex_a710_reset_func #endif #if ERRATA_A710_2017096 - mov x0, x18 - bl errata_a710_2017096_wa + mov x0, x18 + bl errata_a710_2017096_wa +#endif + +#if ERRATA_A710_2083908 + mov x0, x18 + bl errata_a710_2083908_wa #endif isb ret x19 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 6103a5a7b..fd34dcb09 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -425,6 +425,10 @@ ERRATA_A710_1987031 ?=0 # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2081180 ?=0 +# Flag to apply erratum 2083908 workaround during reset. This erratum applies +# to revision r2p0 of the Cortex-A710 cpu and is still open. +ERRATA_A710_2083908 ?=0 + # Flag to apply erratum 2067956 workaround during reset. This erratum applies # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2067956 ?=0 @@ -806,6 +810,10 @@ $(eval $(call add_define,ERRATA_A710_1987031)) $(eval $(call assert_boolean,ERRATA_A710_2081180)) $(eval $(call add_define,ERRATA_A710_2081180)) +# Process ERRATA_A710_2083908 flag +$(eval $(call assert_boolean,ERRATA_A710_2083908)) +$(eval $(call add_define,ERRATA_A710_2083908)) + # Process ERRATA_N2_2067956 flag $(eval $(call assert_boolean,ERRATA_N2_2067956)) $(eval $(call add_define,ERRATA_N2_2067956)) -- cgit v1.2.3 From cb4ec47b5c73e04472984acf821e6be41b98064f Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 4 Aug 2021 19:38:18 -0500 Subject: feat(hcx): add build option to enable FEAT_HCX FEAT_HCX adds the extended hypervisor configuration register (HCRX_EL2) and access to this register must be explicitly enabled through the SCR_EL3.HXEn bit. This patch adds a new build flag ENABLE_FEAT_HCX to allow the register to be accessed from EL2. Signed-off-by: John Powell Change-Id: Ibb36ad90622f1dc857adab4b0d4d7a89456a522b --- Makefile | 2 ++ bl31/bl31_main.c | 9 +++++++++ docs/getting_started/build-options.rst | 4 ++++ include/arch/aarch64/arch.h | 16 ++++++++++++++++ include/arch/aarch64/arch_features.h | 6 ++++++ include/arch/aarch64/arch_helpers.h | 3 +++ include/lib/el3_runtime/aarch64/context.h | 4 ++++ lib/el3_runtime/aarch64/context.S | 10 ++++++++++ lib/el3_runtime/aarch64/context_mgmt.c | 8 ++++++++ make_helpers/defaults.mk | 3 +++ 10 files changed, 65 insertions(+) diff --git a/Makefile b/Makefile index 9d1e94566..a11e55f9f 100644 --- a/Makefile +++ b/Makefile @@ -971,6 +971,7 @@ $(eval $(call assert_booleans,\ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ + ENABLE_FEAT_HCX \ ))) $(eval $(call assert_numerics,\ @@ -1074,6 +1075,7 @@ $(eval $(call add_defines,\ ENABLE_TRBE_FOR_NS \ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ + ENABLE_FEAT_HCX \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index 44bf32cb7..f272af502 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -85,6 +85,15 @@ void bl31_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, /* Perform late platform-specific setup */ bl31_plat_arch_setup(); +#if ENABLE_FEAT_HCX + /* + * Assert that FEAT_HCX is supported on this system, without this check + * an exception would occur during context save/restore if enabled but + * not supported. + */ + assert(is_feat_hcx_present()); +#endif /* ENABLE_FEAT_HCX */ + #if CTX_INCLUDE_PAUTH_REGS /* * Assert that the ARMv8.3-PAuth registers are present or an access diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 115b2b228..0ec10f5db 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -235,6 +235,10 @@ Common build options builds, but this behaviour can be overridden in each platform's Makefile or in the build command line. +- ``ENABLE_FEAT_HCX``: This option sets the bit SCR_EL3.HXEn in EL3 to allow + access to HCRX_EL2 (extended hypervisor control register) from EL2 as well as + adding HCRX_EL2 to the EL2 context save/restore operations. + - ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO) support in GCC for TF-A. This option is currently only supported for AArch64. Default is 0. diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 9ea111452..d260ecf45 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -281,6 +281,11 @@ #define ID_AA64MMFR1_EL1_VHE_SHIFT U(8) #define ID_AA64MMFR1_EL1_VHE_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_HCX_SHIFT U(40) +#define ID_AA64MMFR1_EL1_HCX_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_HCX_SUPPORTED ULL(0x1) +#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0) + /* ID_AA64MMFR2_EL1 definitions */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 @@ -429,6 +434,7 @@ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) +#define SCR_HXEn_BIT (UL(1) << 38) #define SCR_AMVOFFEN_BIT (UL(1) << 35) #define SCR_TWEDEn_BIT (UL(1) << 29) #define SCR_ECVEN_BIT (UL(1) << 28) @@ -1143,6 +1149,16 @@ #define RGSR_EL1 S3_0_C1_C0_5 #define GCR_EL1 S3_0_C1_C0_6 +/******************************************************************************* + * FEAT_HCX - Extended Hypervisor Configuration Register + ******************************************************************************/ +#define HCRX_EL2 S3_4_C1_C2_2 +#define HCRX_EL2_FGTnXS_BIT (UL(1) << 4) +#define HCRX_EL2_FnXS_BIT (UL(1) << 3) +#define HCRX_EL2_EnASR_BIT (UL(1) << 2) +#define HCRX_EL2_EnALS_BIT (UL(1) << 1) +#define HCRX_EL2_EnAS0_BIT (UL(1) << 0) + /******************************************************************************* * Definitions for DynamicIQ Shared Unit registers ******************************************************************************/ diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index dc0b7f306..3ff67e571 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -117,4 +117,10 @@ static inline unsigned int get_mpam_version(void) ID_AA64PFR1_MPAM_FRAC_SHIFT) & ID_AA64PFR1_MPAM_FRAC_MASK)); } +static inline bool is_feat_hcx_present(void) +{ + return (((read_id_aa64mmfr1_el1() >> ID_AA64MMFR1_EL1_HCX_SHIFT) & + ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED); +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index a41b3258e..549ae6600 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -532,6 +532,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(gcr_el1, GCR_EL1) DEFINE_SYSREG_READ_FUNC(rndr) DEFINE_SYSREG_READ_FUNC(rndrrs) +/* FEAT_HCX Register */ +DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) + /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index d449a65ed..c3f41179f 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -228,6 +228,10 @@ // Starting with Armv8.5 #define CTX_SCXTNUM_EL2 U(0x1e0) + +// Register for FEAT_HCX +#define CTX_HCRX_EL2 U(0x1e8) + /* Align to the next 16 byte boundary */ #define CTX_EL2_SYSREGS_END U(0x1f0) diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 40e7ddfa1..e270ad0a9 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -193,6 +193,11 @@ func el2_sysregs_context_save str x13, [x0, #CTX_SCXTNUM_EL2] #endif +#if ENABLE_FEAT_HCX + mrs x14, hcrx_el2 + str x14, [x0, #CTX_HCRX_EL2] +#endif + ret endfunc el2_sysregs_context_save @@ -362,6 +367,11 @@ func el2_sysregs_context_restore msr scxtnum_el2, x13 #endif +#if ENABLE_FEAT_HCX + ldr x14, [x0, #CTX_HCRX_EL2] + msr hcrx_el2, x14 +#endif + ret endfunc el2_sysregs_context_restore diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 52102ddd4..08022d4ad 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -112,6 +112,14 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) if (EP_GET_ST(ep->h.attr) != 0U) scr_el3 |= SCR_ST_BIT; + /* + * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting + * SCR_EL3.HXEn. + */ +#if ENABLE_FEAT_HCX + scr_el3 |= SCR_HXEn_BIT; +#endif + #if RAS_TRAP_LOWER_EL_ERR_ACCESS /* * SCR_EL3.TERR: Trap Error record accesses. Accesses to the RAS ERR diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index c1886218d..18092e7fa 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -121,6 +121,9 @@ ENABLE_BTI := 0 # Use BRANCH_PROTECTION to enable PAUTH. ENABLE_PAUTH := 0 +# Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn. +ENABLE_FEAT_HCX := 0 + # By default BL31 encryption disabled ENCRYPT_BL31 := 0 -- cgit v1.2.3 From 3b994a75306cc487144dd8e2e15433799e62e6f2 Mon Sep 17 00:00:00 2001 From: Rex-BC Chen Date: Tue, 10 Aug 2021 11:10:58 +0800 Subject: feat(plat/mdeiatek/mt8195): add DFD control in SiP service DFD (Design for Debug) is a debugging tool, which scans flip-flops and dumps to internal RAM on the WDT reset. After system reboots, those values could be showed for debugging. BUG=b:192429713 Signed-off-by: Rex-BC Chen Change-Id: I02c6c862b6217bc84c83a09b533bd53ec19b06f7 --- plat/mediatek/mt8195/drivers/dfd/plat_dfd.c | 156 ++++++++++++++++++++++++++ plat/mediatek/mt8195/drivers/dfd/plat_dfd.h | 85 ++++++++++++++ plat/mediatek/mt8195/include/plat_sip_calls.h | 6 +- plat/mediatek/mt8195/include/platform_def.h | 2 + plat/mediatek/mt8195/plat_pm.c | 3 + plat/mediatek/mt8195/plat_sip_calls.c | 6 + plat/mediatek/mt8195/platform.mk | 2 + 7 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 plat/mediatek/mt8195/drivers/dfd/plat_dfd.c create mode 100644 plat/mediatek/mt8195/drivers/dfd/plat_dfd.h diff --git a/plat/mediatek/mt8195/drivers/dfd/plat_dfd.c b/plat/mediatek/mt8195/drivers/dfd/plat_dfd.c new file mode 100644 index 000000000..c083318ff --- /dev/null +++ b/plat/mediatek/mt8195/drivers/dfd/plat_dfd.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include + +static bool dfd_enabled; +static uint64_t dfd_base_addr; +static uint64_t dfd_chain_length; +static uint64_t dfd_cache_dump; + +static void dfd_setup(uint64_t base_addr, uint64_t chain_length, + uint64_t cache_dump) +{ + mmio_write_32(MTK_WDT_LATCH_CTL2, MTK_WDT_LATCH_CTL2_VAL); + mmio_write_32(MTK_WDT_INTERVAL, MTK_WDT_INTERVAL_VAL); + mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_VAL); + mmio_write_32(MTK_DRM_LATCH_CTL1, MTK_DRM_LATCH_CTL1_VAL); + + /* Bit[2] = 0 (default=1), disable dfd apb bus protect_en */ + mmio_clrbits_32(DFD_O_INTRF_MCU_PWR_CTL_MASK, 0x1 << 2); + + /* Bit[0] : enable?mcusys_vproc?external_off?dfd?trigger -> 1 */ + mmio_setbits_32(DFD_V50_GROUP_0_63_DIFF, 0x1); + + /* bit[0]: rg_rw_dfd_internal_dump_en -> 1 */ + /* bit[2]: rg_rw_dfd_clock_stop_en -> 1 */ + sync_writel(DFD_INTERNAL_CTL, 0x5); + + /* bit[13]: xreset_b_update_disable */ + mmio_setbits_32(DFD_INTERNAL_CTL, 0x1 << 13); + + /* + * bit[10:3]: DFD trigger selection mask + * bit[3]: rg_rw_dfd_trigger_sel[0] = 1(enable wdt trigger) + * bit[4]: rg_rw_dfd_trigger_sel[1] = 1(enable HW trigger) + * bit[5]: rg_rw_dfd_trigger_sel[2] = 1(enable SW trigger) + * bit[6]: rg_rw_dfd_trigger_sel[3] = 1(enable SW non-security trigger) + * bit[7]: rg_rw_dfd_trigger_sel[4] = 1(enable timer trigger) + */ + mmio_setbits_32(DFD_INTERNAL_CTL, 0x1F << 3); + + /* + * bit[9] : rg_rw_dfd_trigger_sel[6] = 1(cpu_eb_sw_dfd_trigger) + * bit[10] : rg_rw_dfd_trigger_sel[7] = 1(cpu_eb_wdt_dfd_trigger) + */ + mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 9); + + /* bit[20:19]: rg_dfd_armpll_div_mux_sel switch to PLL2 for DFD */ + mmio_setbits_32(DFD_INTERNAL_CTL, 0x3 << 19); + + /* + * bit[0]: rg_rw_dfd_auto_power_on = 1 + * bit[2:1]: rg_rw_dfd_auto_power_on_dely = 1(10us) + * bit[4:2]: rg_rw_dfd_power_on_wait_time = 1(20us) + */ + mmio_write_32(DFD_INTERNAL_PWR_ON, 0xB); + + /* longest scan chain length */ + mmio_write_32(DFD_CHAIN_LENGTH0, chain_length); + + /* bit[1:0]: rg_rw_dfd_shift_clock_ratio */ + mmio_write_32(DFD_INTERNAL_SHIFT_CLK_RATIO, 0x0); + + /* rg_dfd_test_so_over_64 */ + mmio_write_32(DFD_INTERNAL_TEST_SO_OVER_64, 0x1); + + /* DFD3.0 */ + mmio_write_32(DFD_TEST_SI_0, 0x0); + mmio_write_32(DFD_TEST_SI_1, 0x0); + mmio_write_32(DFD_TEST_SI_2, 0x0); + mmio_write_32(DFD_TEST_SI_3, 0x0); + + /* for iLDO feature */ + sync_writel(DFD_POWER_CTL, 0xF9); + + /* read offset */ + sync_writel(DFD_READ_ADDR, DFD_READ_ADDR_VAL); + + /* for DFD-3.0 setup */ + sync_writel(DFD_V30_CTL, 0xD); + + /* set base address */ + mmio_write_32(DFD_O_SET_BASEADDR_REG, base_addr >> 24); + mmio_write_32(DFD_O_REG_0, 0); + + /* setup global variables for suspend and resume */ + dfd_enabled = true; + dfd_base_addr = base_addr; + dfd_chain_length = chain_length; + dfd_cache_dump = cache_dump; + + if ((cache_dump & DFD_CACHE_DUMP_ENABLE) != 0UL) { + mmio_write_32(MTK_DRM_LATCH_CTL2, MTK_DRM_LATCH_CTL2_CACHE_VAL); + sync_writel(DFD_V35_ENABLE, 0x1); + sync_writel(DFD_V35_TAP_NUMBER, 0xB); + sync_writel(DFD_V35_TAP_EN, DFD_V35_TAP_EN_VAL); + sync_writel(DFD_V35_SEQ0_0, DFD_V35_SEQ0_0_VAL); + + /* Cache dump only mode */ + sync_writel(DFD_V35_CTL, 0x1); + mmio_write_32(DFD_INTERNAL_NUM_OF_TEST_SO_GROUP, 0xF); + mmio_write_32(DFD_CHAIN_LENGTH0, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH1, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH2, DFD_CHAIN_LENGTH_VAL); + mmio_write_32(DFD_CHAIN_LENGTH3, DFD_CHAIN_LENGTH_VAL); + + if ((cache_dump & DFD_PARITY_ERR_TRIGGER) != 0UL) { + sync_writel(DFD_HW_TRIGGER_MASK, 0xC); + mmio_setbits_32(DFD_INTERNAL_CTL, 0x1 << 4); + } + } + dsbsy(); +} + +void dfd_resume(void) +{ + if (dfd_enabled == true) { + dfd_setup(dfd_base_addr, dfd_chain_length, dfd_cache_dump); + } +} + +uint64_t dfd_smc_dispatcher(uint64_t arg0, uint64_t arg1, + uint64_t arg2, uint64_t arg3) +{ + uint64_t ret = 0L; + + switch (arg0) { + case PLAT_MTK_DFD_SETUP_MAGIC: + INFO("[%s] DFD setup call from kernel\n", __func__); + dfd_setup(arg1, arg2, arg3); + break; + case PLAT_MTK_DFD_READ_MAGIC: + /* only allow to access DFD register base + 0x200 */ + if (arg1 <= 0x200) { + ret = mmio_read_32(MISC1_CFG_BASE + arg1); + } + break; + case PLAT_MTK_DFD_WRITE_MAGIC: + /* only allow to access DFD register base + 0x200 */ + if (arg1 <= 0x200) { + sync_writel(MISC1_CFG_BASE + arg1, arg2); + } + break; + default: + ret = MTK_SIP_E_INVALID_PARAM; + break; + } + + return ret; +} diff --git a/plat/mediatek/mt8195/drivers/dfd/plat_dfd.h b/plat/mediatek/mt8195/drivers/dfd/plat_dfd.h new file mode 100644 index 000000000..2a7e9790c --- /dev/null +++ b/plat/mediatek/mt8195/drivers/dfd/plat_dfd.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DFD_H +#define PLAT_DFD_H + +#include +#include +#include + +#define sync_writel(addr, val) do { mmio_write_32((addr), (val)); \ + dsbsy(); \ + } while (0) + +#define PLAT_MTK_DFD_SETUP_MAGIC (0x99716150) +#define PLAT_MTK_DFD_READ_MAGIC (0x99716151) +#define PLAT_MTK_DFD_WRITE_MAGIC (0x99716152) + +#define MTK_DRM_LATCH_CTL1 (DRM_BASE + 0x40) +#define MTK_DRM_LATCH_CTL2 (DRM_BASE + 0x44) + +#define MTK_WDT_BASE (RGU_BASE) +#define MTK_WDT_INTERVAL (MTK_WDT_BASE + 0x10) +#define MTK_WDT_LATCH_CTL2 (MTK_WDT_BASE + 0x48) + +#define MCU_BIU_BASE (MCUCFG_BASE) +#define MISC1_CFG_BASE (MCU_BIU_BASE + 0xE040) +#define DFD_INTERNAL_CTL (MISC1_CFG_BASE + 0x00) +#define DFD_INTERNAL_PWR_ON (MISC1_CFG_BASE + 0x08) +#define DFD_CHAIN_LENGTH0 (MISC1_CFG_BASE + 0x0C) +#define DFD_INTERNAL_SHIFT_CLK_RATIO (MISC1_CFG_BASE + 0x10) +#define DFD_CHAIN_LENGTH1 (MISC1_CFG_BASE + 0x1C) +#define DFD_CHAIN_LENGTH2 (MISC1_CFG_BASE + 0x20) +#define DFD_CHAIN_LENGTH3 (MISC1_CFG_BASE + 0x24) +#define DFD_INTERNAL_TEST_SO_0 (MISC1_CFG_BASE + 0x28) +#define DFD_INTERNAL_NUM_OF_TEST_SO_GROUP (MISC1_CFG_BASE + 0x30) +#define DFD_INTERNAL_TEST_SO_OVER_64 (MISC1_CFG_BASE + 0x34) +#define DFD_INTERNAL_SW_NS_TRIGGER (MISC1_CFG_BASE + 0x3c) +#define DFD_V30_CTL (MISC1_CFG_BASE + 0x48) +#define DFD_V30_BASE_ADDR (MISC1_CFG_BASE + 0x4C) +#define DFD_POWER_CTL (MISC1_CFG_BASE + 0x50) +#define DFD_TEST_SI_0 (MISC1_CFG_BASE + 0x58) +#define DFD_TEST_SI_1 (MISC1_CFG_BASE + 0x5C) +#define DFD_CLEAN_STATUS (MISC1_CFG_BASE + 0x60) +#define DFD_TEST_SI_2 (MISC1_CFG_BASE + 0x1D8) +#define DFD_TEST_SI_3 (MISC1_CFG_BASE + 0x1DC) +#define DFD_READ_ADDR (MISC1_CFG_BASE + 0x1E8) +#define DFD_HW_TRIGGER_MASK (MISC1_CFG_BASE + 0xBC) + +#define DFD_V35_ENABLE (MCU_BIU_BASE + 0xE0A8) +#define DFD_V35_TAP_NUMBER (MCU_BIU_BASE + 0xE0AC) +#define DFD_V35_TAP_EN (MCU_BIU_BASE + 0xE0B0) +#define DFD_V35_CTL (MCU_BIU_BASE + 0xE0B4) +#define DFD_V35_SEQ0_0 (MCU_BIU_BASE + 0xE0C0) +#define DFD_V35_SEQ0_1 (MCU_BIU_BASE + 0xE0C4) +#define DFD_V50_GROUP_0_63_DIFF (MCU_BIU_BASE + 0xE2AC) + +#define DFD_O_PROTECT_EN_REG (0x10001220) +#define DFD_O_INTRF_MCU_PWR_CTL_MASK (0x10001A3C) +#define DFD_O_SET_BASEADDR_REG (0x10043000) +#define DFD_O_REG_0 (0x10001390) + +#define DFD_CACHE_DUMP_ENABLE 1U +#define DFD_PARITY_ERR_TRIGGER 2U + +#define DFD_V35_TAP_EN_VAL (0x43FF) +#define DFD_V35_SEQ0_0_VAL (0x63668820) +#define DFD_READ_ADDR_VAL (0x40000008) +#define DFD_CHAIN_LENGTH_VAL (0xFFFFFFFF) + +#define MTK_WDT_LATCH_CTL2_VAL (0x9507FFFF) +#define MTK_WDT_INTERVAL_VAL (0x6600000A) +#define MTK_DRM_LATCH_CTL2_VAL (0x950600C8) +#define MTK_DRM_LATCH_CTL2_CACHE_VAL (0x95065DC0) + +#define MTK_DRM_LATCH_CTL1_VAL (0x95000013) + +void dfd_resume(void); +uint64_t dfd_smc_dispatcher(uint64_t arg0, uint64_t arg1, + uint64_t arg2, uint64_t arg3); + +#endif /* PLAT_DFD_H */ diff --git a/plat/mediatek/mt8195/include/plat_sip_calls.h b/plat/mediatek/mt8195/include/plat_sip_calls.h index 181aec0f8..ce25c6fd7 100644 --- a/plat/mediatek/mt8195/include/plat_sip_calls.h +++ b/plat/mediatek/mt8195/include/plat_sip_calls.h @@ -10,7 +10,11 @@ /******************************************************************************* * Plat SiP function constants ******************************************************************************/ -#define MTK_PLAT_SIP_NUM_CALLS 2 +#define MTK_PLAT_SIP_NUM_CALLS 4 + +/* DFD */ +#define MTK_SIP_KERNEL_DFD_AARCH32 0x82000205 +#define MTK_SIP_KERNEL_DFD_AARCH64 0xC2000205 /* DP/eDP */ #define MTK_SIP_DP_CONTROL_AARCH32 0x82000523 diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h index 44de8eb3b..68301d6bd 100644 --- a/plat/mediatek/mt8195/include/platform_def.h +++ b/plat/mediatek/mt8195/include/platform_def.h @@ -24,7 +24,9 @@ #define TOPCKGEN_BASE (IO_PHYS + 0x00000000) #define INFRACFG_AO_BASE (IO_PHYS + 0x00001000) #define SPM_BASE (IO_PHYS + 0x00006000) +#define RGU_BASE (IO_PHYS + 0x00007000) #define APMIXEDSYS (IO_PHYS + 0x0000C000) +#define DRM_BASE (IO_PHYS + 0x0000D000) #define SSPM_MBOX_BASE (IO_PHYS + 0x00480000) #define PERICFG_AO_BASE (IO_PHYS + 0x01003000) #define VPPSYS0_BASE (IO_PHYS + 0x04000000) diff --git a/plat/mediatek/mt8195/plat_pm.c b/plat/mediatek/mt8195/plat_pm.c index 2beeb0267..b77ab27a4 100644 --- a/plat/mediatek/mt8195/plat_pm.c +++ b/plat/mediatek/mt8195/plat_pm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -166,6 +167,8 @@ static void plat_mcusys_pwron_common(unsigned int cpu, mt_gic_distif_restore(); gic_sgi_restore_all(); + dfd_resume(); + plat_mt_pm_invoke_no_check(pwr_mcusys_on_finished, cpu, state); } diff --git a/plat/mediatek/mt8195/plat_sip_calls.c b/plat/mediatek/mt8195/plat_sip_calls.c index ee36898ca..ddc750243 100644 --- a/plat/mediatek/mt8195/plat_sip_calls.c +++ b/plat/mediatek/mt8195/plat_sip_calls.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "plat_sip_calls.h" uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid, @@ -35,6 +36,11 @@ uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid, ret = spm_vcorefs_v2_args(x1, x2, x3, &x4); SMC_RET2(handle, ret, x4); break; + case MTK_SIP_KERNEL_DFD_AARCH32: + case MTK_SIP_KERNEL_DFD_AARCH64: + ret = dfd_smc_dispatcher(x1, x2, x3, x4); + SMC_RET1(handle, ret); + break; default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); break; diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk index 48a2f72e3..ef7ff81b5 100644 --- a/plat/mediatek/mt8195/platform.mk +++ b/plat/mediatek/mt8195/platform.mk @@ -15,6 +15,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT}/common/drivers/uart/ \ -I${MTK_PLAT}/common/lpm/ \ -I${MTK_PLAT_SOC}/drivers/dcm \ + -I${MTK_PLAT_SOC}/drivers/dfd \ -I${MTK_PLAT_SOC}/drivers/dp/ \ -I${MTK_PLAT_SOC}/drivers/emi_mpu/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ @@ -60,6 +61,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \ ${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \ + ${MTK_PLAT_SOC}/drivers/dfd/plat_dfd.c \ ${MTK_PLAT_SOC}/drivers/dp/mt_dp.c \ ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ -- cgit v1.2.3 From b3b162f3b48e087f6656513862a6f9e1fa0757b1 Mon Sep 17 00:00:00 2001 From: Pan Gao Date: Tue, 28 Sep 2021 09:07:53 +0800 Subject: feat(plat/mediatek/common): enable software reset for CIRQ CIRQ software reset can be used on all platforms, so we remove CIRQ_NEED_SW_RESET in mt_cirq_sw_reset to enable software reset. BUG=b:192200380, b:201035723 Signed-off-by: Pan Gao Change-Id: Id53ea099ae566bf2a573fca866bd10c60429bd5a --- plat/mediatek/common/mtk_cirq.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/plat/mediatek/common/mtk_cirq.c b/plat/mediatek/common/mtk_cirq.c index de3798684..9cf714449 100644 --- a/plat/mediatek/common/mtk_cirq.c +++ b/plat/mediatek/common/mtk_cirq.c @@ -541,11 +541,9 @@ void mt_cirq_flush(void) void mt_cirq_sw_reset(void) { -#ifdef CIRQ_NEED_SW_RESET uint32_t st; st = mmio_read_32(CIRQ_CON); st |= (CIRQ_SW_RESET << CIRQ_CON_SW_RST_BITS); mmio_write_32(CIRQ_CON, st); -#endif } -- cgit v1.2.3 From dcdbcddebdee8d4d2c6c8316f615b428758b22ac Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 11 May 2021 09:43:37 +0200 Subject: fix: SP UUID little to big endian in TF-A build The UUID field in SP manifest DTS is represented as an array of four integers that the SPMC consumes using the little endian representation. The reason is that those values are directly mapped to the SMCCC section 5.3 recommendation and the way they are exposed to the FFA_PARTITION_INFO_GET interface. Per [1] TF-A build flow expects a big endian representation of the UUID so the sp_mk_generator script is updated to accommodate this conversion. [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/9563 Signed-off-by: Olivier Deprez Change-Id: I7c7b295225e23ea64f49170e27d97442b289703b --- tools/sptool/sp_mk_generator.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/sptool/sp_mk_generator.py b/tools/sptool/sp_mk_generator.py index a37e702bb..f983ff3a2 100755 --- a/tools/sptool/sp_mk_generator.py +++ b/tools/sptool/sp_mk_generator.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -# Copyright (c) 2020, Arm Limited. All rights reserved. +# Copyright (c) 2020-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -110,24 +110,36 @@ with open(gen_file, 'w') as out_file: Extract uuid from partition manifest """ pm_file = open(dts) - uuid_key = "uuid" - for line in pm_file: - if uuid_key in line: - uuid_hex = re.findall(r'\<(.+?)\>', line)[0]; + if "uuid" in line: + # re.findall returns a list of string tuples. + # uuid_hex is the first item in this list representing the four + # uuid hex integers from the manifest uuid field. The heading + # '0x' of the hexadecimal representation is stripped out. + # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; + # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da') + uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0]; + + # uuid_hex is a list of four hex string values + if len(uuid_hex) != 4: + print("ERROR: malformed UUID") + exit(-1) - # PM has uuid in format 0xABC... 0x... 0x... 0x... - # Get rid of '0x' and spaces and convert to string of hex digits - uuid_hex = uuid_hex.replace('0x','').replace(' ','') - # make UUID from a string of hex digits - uuid_std = uuid.UUID(uuid_hex) - # convert UUID to a string of hex digits in standard form - uuid_std = str(uuid_std) + # The uuid field in SP manifest is the little endian representation + # mapped to arguments as described in SMCCC section 5.3. + # Convert each unsigned integer value to a big endian representation + # required by fiptool. + y=list(map(bytearray.fromhex, uuid_hex)) + z=(int.from_bytes(y[0], byteorder='little', signed=False), + int.from_bytes(y[1], byteorder='little', signed=False), + int.from_bytes(y[2], byteorder='little', signed=False), + int.from_bytes(y[3], byteorder='little', signed=False)) + uuid_std = uuid.UUID(f'{z[0]:04x}{z[1]:04x}{z[2]:04x}{z[3]:04x}') """ Append FIP_ARGS """ - out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n") + out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n") """ Append CRT_ARGS -- cgit v1.2.3 From b7bc51a7a747bf40d219b2041e5b3ce56737a71b Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Mon, 6 Sep 2021 10:26:03 +0200 Subject: fix: OP-TEE SP manifest per latest SPMC changes Update UUID to little endian: The SPMC expects a little endian representation of the UUID as an array of four integers in the SP manifest. Add managed exit field and cosmetic comments updates. Signed-off-by: Olivier Deprez Change-Id: Icad93ca70bc27bc9d83b8cf888fe5f8839cb1288 --- plat/arm/board/fvp/fdts/optee_sp_manifest.dts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts index 07235b020..551efe69d 100644 --- a/plat/arm/board/fvp/fdts/optee_sp_manifest.dts +++ b/plat/arm/board/fvp/fdts/optee_sp_manifest.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -16,7 +16,7 @@ /* Properties */ description = "op-tee"; ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */ - uuid = <0x486178e0 0xe7f811e3 0xbc5e0002 0xa5d5c51b>; + uuid = <0xe0786148 0xe311f8e7 0x02005ebc 0x1bc5d5a5>; id = <1>; execution-ctx-count = <8>; exception-level = <2>; /* S-EL1 */ @@ -25,8 +25,9 @@ entrypoint-offset = <0x1000>; xlat-granule = <0>; /* 4KiB */ boot-order = <0>; - messaging-method = <3>; /* Direct messaging only */ - run-time-model = <1>; /* Run to completion */ + messaging-method = <0x3>; /* Direct request/response supported. */ + managed-exit; + run-time-model = <1>; /* SP pre-emptible. */ /* Boot protocol */ gp-register-num = <0x0>; -- cgit v1.2.3 From 46789a7c711d650ae9b2bad0c2b817c4ba4a214a Mon Sep 17 00:00:00 2001 From: Balint Dobszay Date: Fri, 26 Mar 2021 16:23:18 +0100 Subject: build(bl2): enable SP pkg loading for S-EL1 SPMC Currently the SP package loading mechanism is only enabled when S-EL2 SPMC is selected. Remove this limitation. Signed-off-by: Balint Dobszay Change-Id: I5bf5a32248e85a26d0345cacff7d539eed824cfc --- Makefile | 9 ++++++--- docs/getting_started/build-options.rst | 3 +++ make_helpers/defaults.mk | 3 +++ plat/arm/common/arm_bl2_setup.c | 2 +- plat/arm/common/arm_common.mk | 2 +- plat/arm/common/arm_image_load.c | 6 +++--- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 9d1e94566..a76d01fce 100644 --- a/Makefile +++ b/Makefile @@ -529,6 +529,10 @@ ifneq (${SPD},none) ifneq ($(ARM_BL2_SP_LIST_DTS),) DTC_CPPFLAGS += -DARM_BL2_SP_LIST_DTS=$(ARM_BL2_SP_LIST_DTS) endif + + ifneq ($(SP_LAYOUT_FILE),) + BL2_ENABLE_SP_LOAD := 1 + endif else # All other SPDs in spd directory SPD_DIR := spd @@ -902,6 +906,7 @@ endif $(eval $(call assert_booleans,\ $(sort \ ALLOW_RO_XLAT_TABLES \ + BL2_ENABLE_SP_LOAD \ COLD_BOOT_SINGLE_CPU \ CREATE_KEYS \ CTX_INCLUDE_AARCH32_REGS \ @@ -1002,6 +1007,7 @@ $(eval $(call add_defines,\ ALLOW_RO_XLAT_TABLES \ ARM_ARCH_MAJOR \ ARM_ARCH_MINOR \ + BL2_ENABLE_SP_LOAD \ COLD_BOOT_SINGLE_CPU \ CTX_INCLUDE_AARCH32_REGS \ CTX_INCLUDE_FPREGS \ @@ -1103,9 +1109,6 @@ endif # Generate and include sp_gen.mk if SPD is spmd and SP_LAYOUT_FILE is defined ifeq (${SPD},spmd) ifdef SP_LAYOUT_FILE - ifeq (${SPMD_SPM_AT_SEL2},0) - $(error "SPMD with SPM at S-EL1 does not require SP_LAYOUT_FILE") - endif -include $(BUILD_PLAT)/sp_gen.mk FIP_DEPS += sp CRT_DEPS += sp diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 115b2b228..42449db0c 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -55,6 +55,9 @@ Common build options - ``BL2_AT_EL3``: This is an optional build option that enables the use of BL2 at EL3 execution level. +- ``BL2_ENABLE_SP_LOAD``: Boolean option to enable loading SP packages from the + FIP. Automatically enabled if ``SP_LAYOUT_FILE`` is provided. + - ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place (XIP) memory, like BL1. In these use-cases, it is necessary to initialize the RW sections in RAM, while leaving the RO sections in place. This option diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index c1886218d..f26cab649 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -32,6 +32,9 @@ BASE_COMMIT := origin/master # Execute BL2 at EL3 BL2_AT_EL3 := 0 +# Only use SP packages if SP layout JSON is defined +BL2_ENABLE_SP_LOAD := 0 + # BL2 image is stored in XIP memory, for now, this option is only supported # when BL2_AT_EL3 is 1. BL2_IN_XIP_MEM := 0 diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 26af38344..5b26a1d3b 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -233,7 +233,7 @@ int arm_bl2_handle_post_image_load(unsigned int image_id) ******************************************************************************/ int arm_bl2_plat_handle_post_image_load(unsigned int image_id) { -#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 +#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD /* For Secure Partitions we don't need post processing */ if ((image_id >= (MAX_NUMBER_IDS - MAX_SP_IDS)) && (image_id < MAX_NUMBER_IDS)) { diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 4d5e8b4b1..58060dbcf 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -217,7 +217,7 @@ endif ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \ plat/arm/common/fconf/arm_fconf_io.c ifeq (${SPD},spmd) - ifeq (${SPMD_SPM_AT_SEL2},1) + ifeq (${BL2_ENABLE_SP_LOAD},1) ARM_IO_SOURCES += plat/arm/common/fconf/arm_fconf_sp.c endif endif diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c index ebf6dfff8..c411c6cbb 100644 --- a/plat/arm/common/arm_image_load.c +++ b/plat/arm/common/arm_image_load.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,7 @@ void plat_flush_next_bl_params(void) next_bl_params_cpy_ptr); } -#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 +#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD /******************************************************************************* * This function appends Secure Partitions to list of loadable images. ******************************************************************************/ @@ -76,7 +76,7 @@ static void plat_add_sp_images_load_info(struct bl_load_info *load_info) ******************************************************************************/ struct bl_load_info *plat_get_bl_image_load_info(void) { -#if defined(SPD_spmd) && SPMD_SPM_AT_SEL2 +#if defined(SPD_spmd) && BL2_ENABLE_SP_LOAD bl_load_info_t *bl_load_info; bl_load_info = get_bl_load_info_from_mem_params_desc(); -- cgit v1.2.3 From 420c26b33a29c8328a1806ccb2f5a5885041fdfc Mon Sep 17 00:00:00 2001 From: Tinghan Shen Date: Tue, 28 Sep 2021 18:55:45 +0800 Subject: fix(plat/mediatek/mt8183): fix out-of-bound access Fix coverity checks which is found on: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1806/comment/eaec126f_af5eb624/ Change-Id: I9405f7f67aa4115c1a7b8b4623b6b0830e62f814 Signed-off-by: Tinghan Shen --- plat/mediatek/mt8183/drivers/sspm/sspm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.c b/plat/mediatek/mt8183/drivers/sspm/sspm.c index 391763818..6e761243c 100644 --- a/plat/mediatek/mt8183/drivers/sspm/sspm.c +++ b/plat/mediatek/mt8183/drivers/sspm/sspm.c @@ -149,7 +149,7 @@ int sspm_alive_show(void) while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM, &ipi_data, - sizeof(ipi_data)) + sizeof(ipi_data) / sizeof(uint32_t)) && count) { mdelay(100); count--; -- cgit v1.2.3 From cbee43ebd69377bce1c4fa8d40c6fd67f2be2ee4 Mon Sep 17 00:00:00 2001 From: "shriram.k" Date: Wed, 11 Aug 2021 17:39:30 +0530 Subject: feat(plat/arm/sgi): add CPU specific handler for Neoverse V1 The 'CORE_PWRDN_EN' bit of 'CPUPWRCTLR_EL1' register requires an explicit write to clear it for hotplug and idle to function correctly. So add Neoverse V1 CPU specific handler in platform reset handler to clear the CORE_PWRDN_EN bit. Signed-off-by: shriram.k Change-Id: I56084c42a56c401503a751cb518238c83cfca8ac --- plat/arm/css/sgi/aarch64/sgi_helper.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index 04bfb7771..b1a4bb08f 100644 --- a/plat/arm/css/sgi/aarch64/sgi_helper.S +++ b/plat/arm/css/sgi/aarch64/sgi_helper.S @@ -9,6 +9,7 @@ #include #include #include +#include #include .globl plat_arm_calc_core_pos @@ -66,6 +67,7 @@ endfunc plat_arm_calc_core_pos func plat_reset_handler jump_if_cpu_midr CORTEX_A75_MIDR, A75 jump_if_cpu_midr NEOVERSE_N1_MIDR, N1 + jump_if_cpu_midr NEOVERSE_V1_MIDR, V1 ret /* ----------------------------------------------------- @@ -85,4 +87,11 @@ N1: msr NEOVERSE_N1_CPUPWRCTLR_EL1, x0 isb ret + +V1: + mrs x0, NEOVERSE_V1_CPUPWRCTLR_EL1 + bic x0, x0, #NEOVERSE_V1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr NEOVERSE_V1_CPUPWRCTLR_EL1, x0 + isb + ret endfunc plat_reset_handler -- cgit v1.2.3 From d932a5831e26620d61d171d0fd8bc2f14938e6f1 Mon Sep 17 00:00:00 2001 From: "shriram.k" Date: Wed, 11 Aug 2021 17:36:17 +0530 Subject: feat(plat/arm/sgi): add CPU specific handler for Neoverse N2 The 'CORE_PWRDN_EN' bit of 'CPUPWRCTLR_EL1' register requires an explicit write to clear it for hotplug and idle to function correctly. So add Neoverse N2 CPU specific handler in platform reset handler to clear the CORE_PWRDN_EN bit. Signed-off-by: shriram.k Change-Id: If3859447410c4b8e704588993941178fa9411f52 --- plat/arm/css/sgi/aarch64/sgi_helper.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S index b1a4bb08f..ced59e8dd 100644 --- a/plat/arm/css/sgi/aarch64/sgi_helper.S +++ b/plat/arm/css/sgi/aarch64/sgi_helper.S @@ -10,6 +10,7 @@ #include #include #include +#include #include .globl plat_arm_calc_core_pos @@ -68,6 +69,7 @@ func plat_reset_handler jump_if_cpu_midr CORTEX_A75_MIDR, A75 jump_if_cpu_midr NEOVERSE_N1_MIDR, N1 jump_if_cpu_midr NEOVERSE_V1_MIDR, V1 + jump_if_cpu_midr NEOVERSE_N2_MIDR, N2 ret /* ----------------------------------------------------- @@ -94,4 +96,11 @@ V1: msr NEOVERSE_V1_CPUPWRCTLR_EL1, x0 isb ret + +N2: + mrs x0, NEOVERSE_N2_CPUPWRCTLR_EL1 + bic x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT + msr NEOVERSE_N2_CPUPWRCTLR_EL1, x0 + isb + ret endfunc plat_reset_handler -- cgit v1.2.3 From be33dce7407ddec0d6dcab58e7b206688f4a6b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 23 Sep 2021 14:11:25 +0200 Subject: refactor(drivers/marvell/comphy-3700): simplify usage of indirect access on lane2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For code cleanup add two helper functions comphy_sata_set_indirect() and comphy_usb_set_indirect() for SATA and USB 3.0 modes and remove additional 'mode' argument which is not needed anymore. Signed-off-by: Pali Rohár Change-Id: I23146f569db318dbaed5d411d7d175abf6efff85 --- drivers/marvell/comphy/phy-comphy-3700.c | 102 ++++++++++++++++--------------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 6a0e44141..02e1e9e3c 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -214,7 +214,7 @@ static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index) /* It is only used for SATA and USB3 on comphy lane2. */ static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data, - uint16_t mask, int mode) + uint16_t mask, bool is_sata) { /* * When Lane 2 PHY is for USB3, access the PHY registers @@ -224,21 +224,33 @@ static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data, * within the SATA Host Controller registers, Lane 2 base register * offset is 0x200 */ - if (mode == COMPHY_UNUSED) - return; - - if (mode == COMPHY_SATA_MODE) + if (is_sata) { mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET, offset); - else + } else { mmio_write_32(addr + COMPHY_LANE2_INDIR_ADDR_OFFSET, offset + USB3PHY_LANE2_REG_BASE_OFFSET); + } reg_set(addr + COMPHY_LANE2_INDIR_DATA_OFFSET, data, mask); } -/* It is only used USB3 direct access not on comphy lane2. */ +/* It is only used for SATA on comphy lane2. */ +static void comphy_sata_set_indirect(uintptr_t addr, uint32_t reg_offset, + uint16_t data, uint16_t mask) +{ + comphy_set_indirect(addr, reg_offset, data, mask, true); +} + +/* It is only used for USB3 indirect access on comphy lane2. */ +static void comphy_usb3_set_indirect(uintptr_t addr, uint32_t reg_offset, + uint16_t data, uint16_t mask) +{ + comphy_set_indirect(addr, reg_offset, data, mask, false); +} + +/* It is only used for USB3 direct access not on comphy lane2. */ static void comphy_usb3_set_direct(uintptr_t addr, uint32_t reg_offset, - uint16_t data, uint16_t mask, int mode) + uint16_t data, uint16_t mask) { reg_set16((reg_offset * PHY_SHFT(USB3) + addr), data, mask); } @@ -279,7 +291,6 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, int ret = 0; uint32_t offset, data = 0, ref_clk; uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG; - int mode = COMPHY_GET_MODE(comphy_mode); int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode); debug_enter(); @@ -289,8 +300,7 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, /* Clear phy isolation mode to make it work in normal mode */ offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE, - mode); + comphy_sata_set_indirect(comphy_indir_regs, offset, 0, PHY_ISOLATE_MODE); /* 0. Check the Polarity invert bits */ if (invert & COMPHY_POLARITY_TXD_INVERT) @@ -299,13 +309,13 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, data |= RXD_INVERT_BIT; offset = COMPHY_SYNC_PATTERN_REG + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT | - RXD_INVERT_BIT, mode); + comphy_sata_set_indirect(comphy_indir_regs, offset, data, TXD_INVERT_BIT | + RXD_INVERT_BIT); /* 1. Select 40-bit data width width */ offset = COMPHY_LOOPBACK_REG0 + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT, - SEL_DATA_WIDTH_MASK, mode); + comphy_sata_set_indirect(comphy_indir_regs, offset, DATA_WIDTH_40BIT, + SEL_DATA_WIDTH_MASK); /* 2. Select reference clock(25M) and PHY mode (SATA) */ offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET; @@ -314,17 +324,17 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, else ref_clk = REF_CLOCK_SPEED_25M; - comphy_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA, - REF_FREF_SEL_MASK | PHY_MODE_MASK, mode); + comphy_sata_set_indirect(comphy_indir_regs, offset, ref_clk | PHY_MODE_SATA, + REF_FREF_SEL_MASK | PHY_MODE_MASK); /* 3. Use maximum PLL rate (no power save) */ offset = COMPHY_KVCO_CAL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT, - USE_MAX_PLL_RATE_BIT, mode); + comphy_sata_set_indirect(comphy_indir_regs, offset, USE_MAX_PLL_RATE_BIT, + USE_MAX_PLL_RATE_BIT); /* 4. Reset reserved bit */ - comphy_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0, - PHYCTRL_FRM_PIN_BIT, mode); + comphy_sata_set_indirect(comphy_indir_regs, COMPHY_RESERVED_REG, 0, + PHYCTRL_FRM_PIN_BIT); /* 5. Set vendor-specific configuration (It is done in sata driver) */ /* XXX: in U-Boot below sequence was executed in this place, in Linux @@ -589,8 +599,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, uintptr_t reg_base = 0; uint32_t mask, data, addr, cfg, ref_clk; void (*usb3_reg_set)(uintptr_t addr, uint32_t reg_offset, uint16_t data, - uint16_t mask, int mode); - int mode = COMPHY_GET_MODE(comphy_mode); + uint16_t mask); int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode); debug_enter(); @@ -600,7 +609,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, /* Set usb3 reg access func, Lane2 is indirect access */ if (comphy_index == COMPHY_LANE2) { - usb3_reg_set = &comphy_set_indirect; + usb3_reg_set = &comphy_usb3_set_indirect; reg_base = COMPHY_INDIRECT_REG; } else { /* Get the direct access register resource and map */ @@ -619,7 +628,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, mask = PRD_TXDEEMPH0_MASK | PRD_TXMARGIN_MASK | PRD_TXSWING_MASK | CFG_TX_ALIGN_POS_MASK; usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG0_ADDR, PRD_TXDEEMPH0_MASK, - mask, mode); + mask); /* * 2. Set BIT0: enable transmitter in high impedance mode @@ -631,20 +640,20 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, mask = PRD_TXDEEMPH1_MASK | TX_DET_RX_MODE | GEN2_TX_DATA_DLY_MASK | TX_ELEC_IDLE_MODE_EN; data = TX_DET_RX_MODE | GEN2_TX_DATA_DLY_DEFT | TX_ELEC_IDLE_MODE_EN; - usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask, mode); + usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG1_ADDR, data, mask); /* * 3. Set Spread Spectrum Clock Enabled */ usb3_reg_set(reg_base, COMPHY_REG_LANE_CFG4_ADDR, - SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN, mode); + SPREAD_SPECTRUM_CLK_EN, SPREAD_SPECTRUM_CLK_EN); /* * 4. Set Override Margining Controls From the MAC: * Use margining signals from lane configuration */ usb3_reg_set(reg_base, COMPHY_REG_TEST_MODE_CTRL_ADDR, - MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK, mode); + MODE_MARGIN_OVERRIDE, REG_16_BIT_MASK); /* * 5. Set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles @@ -652,13 +661,13 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, */ usb3_reg_set(reg_base, COMPHY_REG_GLOB_CLK_SRC_LO_ADDR, 0x0, (MODE_CLK_SRC | BUNDLE_PERIOD_SEL | BUNDLE_PERIOD_SCALE | - BUNDLE_SAMPLE_CTRL | PLL_READY_DLY), mode); + BUNDLE_SAMPLE_CTRL | PLL_READY_DLY)); /* * 6. Set G2 Spread Spectrum Clock Amplitude at 4K */ usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_2, - G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK, mode); + G2_TX_SSC_AMP_VALUE_20, G2_TX_SSC_AMP_MASK); /* * 7. Unset G3 Spread Spectrum Clock Amplitude @@ -667,7 +676,7 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, mask = G3_TX_SSC_AMP_MASK | G3_VREG_RXTX_MAS_ISET_MASK | RSVD_PH03FH_6_0_MASK; usb3_reg_set(reg_base, COMPHY_REG_GEN2_SET_3, - G3_VREG_RXTX_MAS_ISET_60U, mask, mode); + G3_VREG_RXTX_MAS_ISET_60U, mask); /* * 8. Check crystal jumper setting and program the Power and PLL Control @@ -688,39 +697,37 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, REF_FREF_SEL_MASK; data = PU_IVREF_BIT | PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT | PU_TX_INTP_BIT | PU_DFE_BIT | PHY_MODE_USB3 | ref_clk; - usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask, mode); + usb3_reg_set(reg_base, COMPHY_POWER_PLL_CTRL, data, mask); mask = CFG_PM_OSCCLK_WAIT_MASK | CFG_PM_RXDEN_WAIT_MASK | CFG_PM_RXDLOZ_WAIT_MASK; data = CFG_PM_RXDEN_WAIT_1_UNIT | cfg; - usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask, mode); + usb3_reg_set(reg_base, COMPHY_REG_PWR_MGM_TIM1_ADDR, data, mask); /* * 9. Enable idle sync */ data = UNIT_CTRL_DEFAULT_VALUE | IDLE_SYNC_EN; - usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK, - mode); + usb3_reg_set(reg_base, COMPHY_REG_UNIT_CTRL_ADDR, data, REG_16_BIT_MASK); /* * 10. Enable the output of 500M clock */ data = MISC_REG0_DEFAULT_VALUE | CLK500M_EN; - usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK, - mode); + usb3_reg_set(reg_base, COMPHY_MISC_REG0_ADDR, data, REG_16_BIT_MASK); /* * 11. Set 20-bit data width */ usb3_reg_set(reg_base, COMPHY_LOOPBACK_REG0, DATA_WIDTH_20BIT, - REG_16_BIT_MASK, mode); + REG_16_BIT_MASK); /* * 12. Override Speed_PLL value and use MAC PLL */ usb3_reg_set(reg_base, COMPHY_KVCO_CAL_CTRL, (SPEED_PLL_VALUE_16 | USE_MAX_PLL_RATE_BIT), - REG_16_BIT_MASK, mode); + REG_16_BIT_MASK); /* * 13. Check the Polarity invert bit @@ -733,27 +740,26 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, data |= RXD_INVERT_BIT; } mask = TXD_INVERT_BIT | RXD_INVERT_BIT; - usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask, mode); + usb3_reg_set(reg_base, COMPHY_SYNC_PATTERN_REG, data, mask); /* * 14. Set max speed generation to USB3.0 5Gbps */ usb3_reg_set(reg_base, COMPHY_SYNC_MASK_GEN_REG, PHY_GEN_USB3_5G, - PHY_GEN_MAX_MASK, mode); + PHY_GEN_MAX_MASK); /* * 15. Set capacitor value for FFE gain peaking to 0xF */ usb3_reg_set(reg_base, COMPHY_REG_GEN3_SETTINGS_3, - COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK, - mode); + COMPHY_GEN_FFE_CAP_SEL_VALUE, COMPHY_GEN_FFE_CAP_SEL_MASK); /* * 16. Release SW reset */ data = MODE_CORE_CLK_FREQ_SEL | MODE_PIPE_WIDTH_32 | MODE_REFDIV_BY_4; usb3_reg_set(reg_base, COMPHY_REG_GLOB_PHY_CTRL0_ADDR, data, - REG_16_BIT_MASK, mode); + REG_16_BIT_MASK); /* Wait for > 55 us to allow PCLK be enabled */ udelay(PLL_SET_DELAY_US); @@ -928,13 +934,13 @@ static int mvebu_a3700_comphy_sata_power_off(void) /* Set phy isolation mode */ offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE, - PHY_ISOLATE_MODE, COMPHY_SATA_MODE); + comphy_sata_set_indirect(comphy_indir_regs, offset, PHY_ISOLATE_MODE, + PHY_ISOLATE_MODE); /* Power off PLL, Tx, Rx */ offset = COMPHY_POWER_PLL_CTRL + SATAPHY_LANE2_REG_BASE_OFFSET; - comphy_set_indirect(comphy_indir_regs, offset, 0, - PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT, COMPHY_SATA_MODE); + comphy_sata_set_indirect(comphy_indir_regs, offset, 0, + PU_PLL_BIT | PU_RX_BIT | PU_TX_BIT); debug_exit(); -- cgit v1.2.3 From 0694b81386aebd06a0dba5d16788a66fd83c5f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 23 Sep 2021 15:08:00 +0200 Subject: refactor(drivers/marvell/comphy-3700): simplify usage of comphy_sgmii_phy_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parameter 'comphy_index' is not used and parameter 'mode' is used only to check if speed is 1 Gbps or not. Remove parameter 'comphy_index' and instead of 32-bit variable 'mode', pass only boolean value which represents 1 Gbps speed. Signed-off-by: Pali Rohár Change-Id: I018d158f689ddf7d1f57003717d709c00d988fba --- drivers/marvell/comphy/phy-comphy-3700.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 02e1e9e3c..3b904d307 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -255,8 +255,7 @@ static void comphy_usb3_set_direct(uintptr_t addr, uint32_t reg_offset, reg_set16((reg_offset * PHY_SHFT(USB3) + addr), data, mask); } -static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode, - uintptr_t sd_ip_addr) +static void comphy_sgmii_phy_init(uintptr_t sd_ip_addr, bool is_1gbps) { const int fix_arr_sz = ARRAY_SIZE(sgmii_phy_init_fix); int addr, fix_idx; @@ -271,8 +270,7 @@ static void comphy_sgmii_phy_init(uint32_t comphy_index, uint32_t mode, * comparison to 3.125 Gbps values. These register values are * stored in "sgmii_phy_init_fix" array. */ - if ((mode != COMPHY_SGMII_MODE) && - (sgmii_phy_init_fix[fix_idx].addr == addr)) { + if (!is_1gbps && sgmii_phy_init_fix[fix_idx].addr == addr) { /* Use new value */ val = sgmii_phy_init_fix[fix_idx].value; if (fix_idx < fix_arr_sz) @@ -491,7 +489,7 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, debug("Running C-DPI phy init %s mode\n", mode == COMPHY_2500BASEX_MODE ? "2G5" : "1G"); if (get_ref_clk() == 40) - comphy_sgmii_phy_init(comphy_index, mode, sd_ip_addr); + comphy_sgmii_phy_init(sd_ip_addr, mode != COMPHY_2500BASEX_MODE); /* * 14. [Simulation Only] should not be used for real chip. -- cgit v1.2.3 From c074f70ce5d85e1735b589b323fac99d7eb988b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 23 Sep 2021 18:19:24 +0200 Subject: fix(drivers/marvell/comphy-3700): fix address overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Physical address has to be stored in 64-bit data type as Armada 3720 is 64-bit platform. Driver already uses uintptr_t type for this purpise. Change type of 'offset' variables in mvebu_a3700_comphy_usb3_power_on() and mvebu_a3700_comphy_sgmii_power_on() / off() functions to uintptr_t as in this variable is stored physical address of registers. Signed-off-by: Pali Rohár Change-Id: I69581714f8899d21cc1a27005747708f0f1cd933 --- drivers/marvell/comphy/phy-comphy-3700.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 3b904d307..a59fbd548 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -364,7 +364,8 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, uint32_t comphy_mode) { int ret = 0; - uint32_t mask, data, offset; + uint32_t mask, data; + uintptr_t offset; uintptr_t sd_ip_addr; int mode = COMPHY_GET_MODE(comphy_mode); int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode); @@ -576,7 +577,8 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index) { int ret = 0; - uint32_t mask, data, offset; + uintptr_t offset; + uint32_t mask, data; debug_enter(); @@ -595,7 +597,8 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, { int ret = 0; uintptr_t reg_base = 0; - uint32_t mask, data, addr, cfg, ref_clk; + uintptr_t addr; + uint32_t mask, data, cfg, ref_clk; void (*usb3_reg_set)(uintptr_t addr, uint32_t reg_offset, uint16_t data, uint16_t mask); int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode); -- cgit v1.2.3 From 49b664e75f43fda08dddef4f0510d346bdd25565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 23 Sep 2021 14:47:18 +0200 Subject: fix(drivers/marvell/comphy-3700): handle failures in power functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subroutines in power functions may fail. So propagate failures from subroutines back to the caller of power function with appropriate error code in return value. Function polling_with_timeout() returns last value from polled register on failure and zero on success. So return -ETIMEDOUT on error from power functions like it is doing Marvell comphy-cp110 driver. Signed-off-by: Pali Rohár Change-Id: I6c709c0c9616ab26829616a42a85b713f314b201 --- drivers/marvell/comphy/phy-comphy-3700.c | 61 +++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index a59fbd548..0ad14a800 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -118,7 +118,7 @@ static uint16_t sgmii_phy_init[512] = { }; /* PHY selector configures with corresponding modes */ -static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index, +static int mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index, uint32_t comphy_mode) { uint32_t reg; @@ -168,9 +168,10 @@ static void mvebu_a3700_comphy_set_phy_selector(uint8_t comphy_index, } mmio_write_32(MVEBU_COMPHY_REG_BASE + COMPHY_SELECTOR_PHY_REG, reg); - return; + return 0; error: ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode); + return -EINVAL; } /* @@ -286,7 +287,7 @@ static void comphy_sgmii_phy_init(uintptr_t sd_ip_addr, bool is_1gbps) static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, uint32_t comphy_mode) { - int ret = 0; + int ret; uint32_t offset, data = 0, ref_clk; uintptr_t comphy_indir_regs = COMPHY_INDIRECT_REG; int invert = COMPHY_GET_POLARITY_INVERT(comphy_mode); @@ -294,7 +295,10 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, debug_enter(); /* Configure phy selector for SATA */ - mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + if (ret) { + return ret; + } /* Clear phy isolation mode to make it work in normal mode */ offset = COMPHY_ISOLATION_CTRL_REG + SATAPHY_LANE2_REG_BASE_OFFSET; @@ -354,16 +358,19 @@ static int mvebu_a3700_comphy_sata_power_on(uint8_t comphy_index, COMPHY_LANE2_INDIR_DATA_OFFSET, PLL_READY_TX_BIT, PLL_READY_TX_BIT, COMPHY_PLL_TIMEOUT, REG_32BIT); + if (ret) { + return -ETIMEDOUT; + } debug_exit(); - return ret; + return 0; } static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, uint32_t comphy_mode) { - int ret = 0; + int ret; uint32_t mask, data; uintptr_t offset; uintptr_t sd_ip_addr; @@ -373,7 +380,10 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, debug_enter(); /* Set selector */ - mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + if (ret) { + return ret; + } /* Serdes IP Base address * COMPHY Lane0 -- USB3/GBE1 @@ -534,8 +544,10 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT, PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT, COMPHY_PLL_TIMEOUT, REG_32BIT); - if (ret) + if (ret) { ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index); + return -ETIMEDOUT; + } /* * 19. Set COMPHY input port PIN_TX_IDLE=0 @@ -558,25 +570,27 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index, PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT, PHY_PLL_READY_TX_BIT | PHY_PLL_READY_RX_BIT, COMPHY_PLL_TIMEOUT, REG_32BIT); - if (ret) + if (ret) { ERROR("Failed to lock PLL for SGMII PHY %d\n", comphy_index); - + return -ETIMEDOUT; + } ret = polling_with_timeout(MVEBU_COMPHY_REG_BASE + COMPHY_PHY_STATUS_OFFSET(comphy_index), PHY_RX_INIT_DONE_BIT, PHY_RX_INIT_DONE_BIT, COMPHY_PLL_TIMEOUT, REG_32BIT); - if (ret) + if (ret) { ERROR("Failed to init RX of SGMII PHY %d\n", comphy_index); + return -ETIMEDOUT; + } debug_exit(); - return ret; + return 0; } static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index) { - int ret = 0; uintptr_t offset; uint32_t mask, data; @@ -589,13 +603,13 @@ static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index) debug_exit(); - return ret; + return 0; } static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, uint32_t comphy_mode) { - int ret = 0; + int ret; uintptr_t reg_base = 0; uintptr_t addr; uint32_t mask, data, cfg, ref_clk; @@ -606,7 +620,10 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, debug_enter(); /* Set phy seclector */ - mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + if (ret) { + return ret; + } /* Set usb3 reg access func, Lane2 is indirect access */ if (comphy_index == COMPHY_LANE2) { @@ -778,12 +795,14 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index, TXDCLK_PCLK_EN, TXDCLK_PCLK_EN, COMPHY_PLL_TIMEOUT, REG_16BIT); } - if (ret) + if (ret) { ERROR("Failed to lock USB3 PLL\n"); + return -ETIMEDOUT; + } debug_exit(); - return ret; + return 0; } static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index, @@ -869,12 +888,14 @@ static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index, ret = polling_with_timeout(LANE_STATUS1_ADDR(PCIE) + COMPHY_SD_ADDR, TXDCLK_PCLK_EN, TXDCLK_PCLK_EN, COMPHY_PLL_TIMEOUT, REG_16BIT); - if (ret) + if (ret) { ERROR("Failed to lock PCIE PLL\n"); + return -ETIMEDOUT; + } debug_exit(); - return ret; + return 0; } int mvebu_3700_comphy_power_on(uint8_t comphy_index, uint32_t comphy_mode) -- cgit v1.2.3 From c0a909cdcce2d9a2ceefe672ad2fc1cae7e39ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 24 Sep 2021 14:43:54 +0200 Subject: fix(drivers/marvell/comphy-cp110): fix error code in pcie power on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function polling_with_timeout() returns last value from polled register on failure and zero on success. So set "ret" variable to error code -ETIMEDOUT on error like it is done in other functions. Signed-off-by: Pali Rohár Change-Id: I16cac81bbcbe2113e139722dc0e8fc2b85428d1b --- drivers/marvell/comphy/phy-comphy-cp110.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index d10425b36..e7cde759f 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -1730,11 +1730,13 @@ static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base, HPIPE_LANE_STATUS1_REG; data = HPIPE_LANE_STATUS1_PCLK_EN_MASK; mask = data; - ret = polling_with_timeout(addr, data, mask, + data = polling_with_timeout(addr, data, mask, PLL_LOCK_TIMEOUT, REG_32BIT); - if (ret) + if (data) { ERROR("Failed to lock PCIE PLL\n"); + ret = -ETIMEDOUT; + } } } -- cgit v1.2.3 From 03b201c0fbc14a3a5c0f8f862cc8b9bd052ba09e Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Wed, 21 Oct 2020 13:34:40 -0500 Subject: fvp_r: initial platform port for fvp_r Creating a platform port for FVP_R based on the FVP platform. Differences including only-BL1, aarch64, Secure only, and EL2 being the ELmax (No EL3). Signed-off-by: Lauren Wehrmeister Change-Id: I1283e033fbd4e03c397d0a2c10c4139548b4eee4 --- include/plat/arm/common/arm_def.h | 13 +- plat/arm/board/fvp_r/fvp_r_bl1_setup.c | 67 ++++++++ plat/arm/board/fvp_r/fvp_r_common.c | 235 ++++++++++++++++++++++++++ plat/arm/board/fvp_r/fvp_r_def.h | 109 ++++++++++++ plat/arm/board/fvp_r/fvp_r_err.c | 48 ++++++ plat/arm/board/fvp_r/fvp_r_helpers.S | 166 ++++++++++++++++++ plat/arm/board/fvp_r/fvp_r_io_storage.c | 115 +++++++++++++ plat/arm/board/fvp_r/fvp_r_private.h | 23 +++ plat/arm/board/fvp_r/fvp_r_stack_protector.c | 24 +++ plat/arm/board/fvp_r/fvp_r_trusted_boot.c | 73 ++++++++ plat/arm/board/fvp_r/include/plat.ld.S | 11 ++ plat/arm/board/fvp_r/include/platform_def.h | 242 +++++++++++++++++++++++++++ plat/arm/board/fvp_r/platform.mk | 131 +++++++++++++++ 13 files changed, 1255 insertions(+), 2 deletions(-) create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_setup.c create mode 100644 plat/arm/board/fvp_r/fvp_r_common.c create mode 100644 plat/arm/board/fvp_r/fvp_r_def.h create mode 100644 plat/arm/board/fvp_r/fvp_r_err.c create mode 100644 plat/arm/board/fvp_r/fvp_r_helpers.S create mode 100644 plat/arm/board/fvp_r/fvp_r_io_storage.c create mode 100644 plat/arm/board/fvp_r/fvp_r_private.h create mode 100644 plat/arm/board/fvp_r/fvp_r_stack_protector.c create mode 100644 plat/arm/board/fvp_r/fvp_r_trusted_boot.c create mode 100644 plat/arm/board/fvp_r/include/plat.ld.S create mode 100644 plat/arm/board/fvp_r/include/platform_def.h create mode 100644 plat/arm/board/fvp_r/platform.mk diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index ae80628f1..9d47b903d 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -59,7 +59,12 @@ #define ARM_DRAM_ID 2 /* The first 4KB of Trusted SRAM are used as shared memory */ +#ifdef __PLAT_ARM_TRUSTED_SRAM_BASE__ +#define ARM_TRUSTED_SRAM_BASE PLAT_ARM_TRUSTED_SRAM_BASE +#else #define ARM_TRUSTED_SRAM_BASE UL(0x04000000) +#endif /* __PLAT_ARM_TRUSTED_SRAM_BASE__ */ + #define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE #define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */ @@ -149,8 +154,12 @@ ARM_TZC_DRAM1_SIZE) #define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ ARM_NS_DRAM1_SIZE - 1U) - +#ifdef __PLAT_ARM_DRAM1_BASE__ +#define ARM_DRAM1_BASE PLAT_ARM_DRAM1_BASE +#else #define ARM_DRAM1_BASE ULL(0x80000000) +#endif /* __PLAT_ARM_DRAM1_BASE__ */ + #define ARM_DRAM1_SIZE ULL(0x80000000) #define ARM_DRAM1_END (ARM_DRAM1_BASE + \ ARM_DRAM1_SIZE - 1U) diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c new file mode 100644 index 000000000..91709d84b --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#include "fvp_r_private.h" +#include +#include +#include +#include + + +/******************************************************************************* + * Perform any BL1 specific platform actions. + ******************************************************************************/ +void bl1_early_platform_setup(void) +{ + arm_bl1_early_platform_setup(); + + /* Initialize the platform config for future decision making */ + fvp_config_setup(); + + /* + * Initialize Interconnect for this cluster during cold boot. + * No need for locks as no other CPU is active. + */ + fvp_interconnect_init(); + /* + * Enable coherency in Interconnect for the primary CPU's cluster. + */ + fvp_interconnect_enable(); +} + +void plat_arm_secure_wdt_start(void) +{ + sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); +} + +void plat_arm_secure_wdt_stop(void) +{ + sp805_stop(ARM_SP805_TWDG_BASE); +} + +void bl1_platform_setup(void) +{ + arm_bl1_platform_setup(); + + /* Initialize System level generic or SP804 timer */ + fvp_timer_init(); +} + +__dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) +{ + /* Setup the watchdog to reset the system as soon as possible */ + sp805_refresh(ARM_SP805_TWDG_BASE, 1U); + + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/fvp_r/fvp_r_common.c b/plat/arm/board/fvp_r/fvp_r_common.c new file mode 100644 index 000000000..693a6d795 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_common.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fvp_r_private.h" +#include +#include +#include +#include + + +/* Defines for GIC Driver build time selection */ +#define FVP_R_GICV3 2 + +/******************************************************************************* + * arm_config holds the characteristics of the differences between the FVP_R + * platforms. It will be populated during cold boot at each boot stage by the + * primary before enabling the MPU (to allow interconnect configuration) & + * used thereafter. Each BL will have its own copy to allow independent + * operation. + ******************************************************************************/ +arm_config_t arm_config; + +#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ + DEVICE0_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \ + DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Need to be mapped with write permissions in order to set a new non-volatile + * counter value. + */ +#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \ + DEVICE2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/* + * Table of memory regions for various BL stages to map using the MPU. + * This doesn't include Trusted SRAM as setup_page_tables() already takes care + * of mapping it. + * + * The flash needs to be mapped as writable in order to erase the FIP's Table of + * Contents in case of unrecoverable error (see plat_error_handler()). + */ +#ifdef IMAGE_BL1 +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + V2M_MAP_FLASH0_RW, + V2M_MAP_IOFPGA, + MAP_DEVICE0, + MAP_DEVICE1, +#if TRUSTED_BOARD_BOOT + /* To access the Root of Trust Public Key registers. */ + MAP_DEVICE2, + /* Map DRAM to authenticate NS_BL2U image. */ + ARM_MAP_NS_DRAM1, +#endif + {0} +}; +#endif + +ARM_CASSERT_MMAP + +#if FVP_R_INTERCONNECT_DRIVER != FVP_R_CCN +static const int fvp_cci400_map[] = { + PLAT_FVP_R_CCI400_CLUS0_SL_PORT, + PLAT_FVP_R_CCI400_CLUS1_SL_PORT, +}; + +static const int fvp_cci5xx_map[] = { + PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT, + PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT, +}; + +static unsigned int get_interconnect_master(void) +{ + unsigned int master; + u_register_t mpidr; + + mpidr = read_mpidr_el1(); + master = ((arm_config.flags & ARM_CONFIG_FVP_SHIFTED_AFF) != 0U) ? + MPIDR_AFFLVL2_VAL(mpidr) : MPIDR_AFFLVL1_VAL(mpidr); + + assert(master < FVP_R_CLUSTER_COUNT); + return master; +} +#endif + +/******************************************************************************* + * Initialize the platform config for future decision making + ******************************************************************************/ +void __init fvp_config_setup(void) +{ + arm_config.flags |= ARM_CONFIG_BASE_MMAP; + + /* + * We assume that the presence of MT bit, and therefore shifted + * affinities, is uniform across the platform: either all CPUs, or no + * CPUs implement it. + */ + if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0U) { + arm_config.flags |= ARM_CONFIG_FVP_SHIFTED_AFF; + } +} + + +void __init fvp_interconnect_init(void) +{ +#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN + if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { + ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported"); + panic(); + } + + plat_arm_interconnect_init(); +#else + uintptr_t cci_base = 0U; + const int *cci_map = NULL; + unsigned int map_size = 0U; + + /* Initialize the right interconnect */ + if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI5XX) != 0U) { + cci_base = PLAT_FVP_R_CCI5XX_BASE; + cci_map = fvp_cci5xx_map; + map_size = ARRAY_SIZE(fvp_cci5xx_map); + } else if ((arm_config.flags & ARM_CONFIG_FVP_HAS_CCI400) != 0U) { + cci_base = PLAT_FVP_R_CCI400_BASE; + cci_map = fvp_cci400_map; + map_size = ARRAY_SIZE(fvp_cci400_map); + } else { + return; + } + + assert(cci_base != 0U); + assert(cci_map != NULL); + cci_init(cci_base, cci_map, map_size); +#endif +} + +void fvp_interconnect_enable(void) +{ +#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN + plat_arm_interconnect_enter_coherency(); +#else + unsigned int master; + + if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | + ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { + master = get_interconnect_master(); + cci_enable_snoop_dvm_reqs(master); + } +#endif +} + +void fvp_interconnect_disable(void) +{ +#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN + plat_arm_interconnect_exit_coherency(); +#else + unsigned int master; + + if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | + ARM_CONFIG_FVP_HAS_CCI5XX)) != 0U) { + master = get_interconnect_master(); + cci_disable_snoop_dvm_reqs(master); + } +#endif +} + +#if TRUSTED_BOARD_BOOT +int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) +{ + assert(heap_addr != NULL); + assert(heap_size != NULL); + + return arm_get_mbedtls_heap(heap_addr, heap_size); +} +#endif + +void fvp_timer_init(void) +{ +#if USE_SP804_TIMER + /* Enable the clock override for SP804 timer 0, which means that no + * clock dividers are applied and the raw (35MHz) clock will be used. + */ + mmio_write_32(V2M_SP810_BASE, FVP_R_SP810_CTRL_TIM0_OV); + + /* Initialize delay timer driver using SP804 dual timer 0 */ + sp804_timer_init(V2M_SP804_TIMER0_BASE, + SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); +#else + generic_delay_timer_init(); + + /* Enable System level generic timer */ + mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, + CNTCR_FCREQ(0U) | CNTCR_EN); +#endif /* USE_SP804_TIMER */ +} + +/* Get SOC version */ +int32_t plat_get_soc_version(void) +{ + return (int32_t) + ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT) + | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT) + | FVP_R_SOC_ID); +} + +/* Get SOC revision */ +int32_t plat_get_soc_revision(void) +{ + unsigned int sys_id; + + sys_id = mmio_read_32(V2M_SYSREGS_BASE + V2M_SYS_ID); + return (int32_t)((sys_id >> V2M_SYS_ID_REV_SHIFT) & + V2M_SYS_ID_REV_MASK); +} diff --git a/plat/arm/board/fvp_r/fvp_r_def.h b/plat/arm/board/fvp_r/fvp_r_def.h new file mode 100644 index 000000000..587832f1c --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_def.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_R_DEF_H +#define FVP_R_DEF_H + +#include + +#ifndef FVP_R_CLUSTER_COUNT +#error "FVP_R_CLUSTER_COUNT is not set in makefile" +#endif + +#ifndef FVP_R_MAX_CPUS_PER_CLUSTER +#error "FVP_R_MAX_CPUS_PER_CLUSTER is not set in makefile" +#endif + +#ifndef FVP_R_MAX_PE_PER_CPU +#error "FVP_R_MAX_PE_PER_CPU is not set in makefile" +#endif + +#define FVP_R_PRIMARY_CPU 0x0 + +/* Defines for the Interconnect build selection */ +#define FVP_R_CCI 1 +#define FVP_R_CCN 2 + +/****************************************************************************** + * Definition of platform soc id + *****************************************************************************/ +#define FVP_R_SOC_ID 0 + +/******************************************************************************* + * FVP_R memory map related constants + ******************************************************************************/ + +#define FLASH1_BASE UL(0x0c000000) +#define FLASH1_SIZE UL(0x04000000) + +#define PSRAM_BASE UL(0x14000000) +#define PSRAM_SIZE UL(0x04000000) + +#define VRAM_BASE UL(0x18000000) +#define VRAM_SIZE UL(0x02000000) + +/* Aggregate of all devices in the first GB */ +#define DEVICE0_BASE UL(0x20000000) +#define DEVICE0_SIZE UL(0x0c200000) + +/* + * In case of FVP_R models with CCN, the CCN register space overlaps into + * the NSRAM area. + */ +#define DEVICE1_BASE UL(0x2e000000) +#define DEVICE1_SIZE UL(0x1A00000) +#define NSRAM_BASE UL(0x2e000000) +#define NSRAM_SIZE UL(0x10000) +/* Devices in the second GB */ +#define DEVICE2_BASE UL(0x7fe00000) +#define DEVICE2_SIZE UL(0x00200000) + +/* Non-volatile counters */ +#define TRUSTED_NVCTR_BASE UL(0x7fe70000) +#define TFW_NVCTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0000)) +#define TFW_NVCTR_SIZE UL(4) +#define NTFW_CTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0004)) +#define NTFW_CTR_SIZE UL(4) + +/* Keys */ +#define SOC_KEYS_BASE UL(0x7fe80000) +#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + UL(0x0000)) +#define TZ_PUB_KEY_HASH_SIZE UL(32) +#define HU_KEY_BASE (SOC_KEYS_BASE + UL(0x0020)) +#define HU_KEY_SIZE UL(16) +#define END_KEY_BASE (SOC_KEYS_BASE + UL(0x0044)) +#define END_KEY_SIZE UL(32) + +/* Constants to distinguish FVP_R type */ +#define HBI_BASE_FVP_R U(0x020) +#define REV_BASE_FVP_R_V0 U(0x0) +#define REV_BASE_FVP_R_REVC U(0x2) + +#define HBI_FOUNDATION_FVP_R U(0x010) +#define REV_FOUNDATION_FVP_R_V2_0 U(0x0) +#define REV_FOUNDATION_FVP_R_V2_1 U(0x1) +#define REV_FOUNDATION_FVP_R_v9_1 U(0x2) +#define REV_FOUNDATION_FVP_R_v9_6 U(0x3) + +#define BLD_GIC_VE_MMAP U(0x0) +#define BLD_GIC_A53A57_MMAP U(0x1) + +#define ARCH_MODEL U(0x1) + +/* FVP_R Power controller base address*/ +#define PWRC_BASE UL(0x1c100000) + +/* FVP_R SP804 timer frequency is 35 MHz*/ +#define SP804_TIMER_CLKMULT 1 +#define SP804_TIMER_CLKDIV 35 + +/* SP810 controller. FVP_R specific flags */ +#define FVP_R_SP810_CTRL_TIM0_OV BIT_32(16) +#define FVP_R_SP810_CTRL_TIM1_OV BIT_32(18) +#define FVP_R_SP810_CTRL_TIM2_OV BIT_32(20) +#define FVP_R_SP810_CTRL_TIM3_OV BIT_32(22) + +#endif /* FVP_R_DEF_H */ diff --git a/plat/arm/board/fvp_r/fvp_r_err.c b/plat/arm/board/fvp_r/fvp_r_err.c new file mode 100644 index 000000000..0f7aeac02 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_err.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +/* + * FVP_R error handler + */ +__dead2 void plat_arm_error_handler(int err) +{ + int ret; + + switch (err) { + case -ENOENT: + case -EAUTH: + /* Image load or authentication error. Erase the ToC */ + INFO("Erasing FIP ToC from flash...\n"); + (void)nor_unlock(PLAT_ARM_FIP_BASE); + ret = nor_word_program(PLAT_ARM_FIP_BASE, 0); + if (ret != 0) { + ERROR("Cannot erase ToC\n"); + } else { + INFO("Done\n"); + } + break; + default: + /* Unexpected error */ + break; + } + + (void)console_flush(); + + /* Setup the watchdog to reset the system as soon as possible */ + sp805_refresh(ARM_SP805_TWDG_BASE, 1U); + + while (true) { + wfi(); + } +} diff --git a/plat/arm/board/fvp_r/fvp_r_helpers.S b/plat/arm/board/fvp_r/fvp_r_helpers.S new file mode 100644 index 000000000..f7a04d8bc --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_helpers.S @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include + + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl plat_arm_calc_core_pos + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * TODO: Should we read the PSYS register to make sure + * that the request has gone through. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* --------------------------------------------- + * Power down this cpu. + * TODO: Do we need to worry about powering the + * cluster down as well here? That will need + * locks which we won't have unless an elf- + * loader zeroes out the zi section. + * --------------------------------------------- + */ + mrs x0, mpidr_el1 + mov_imm x1, PWRC_BASE + str w0, [x1, #PPOFFR_OFF] + + /* --------------------------------------------- + * There is no sane reason to come out of this + * wfi so panic if we do. This cpu will be pow- + * ered on and reset by the cpu_on pm api + * --------------------------------------------- + */ + dsb sy + wfi + no_ret plat_panic_handler +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * uintptr_t plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and warm + * boot. On FVP_R, this information can be queried from the power + * controller. The Power Control SYS Status Register (PSYSR) indicates + * the wake-up reason for the CPU. + * + * For a cold boot, return 0. + * For a warm boot, read the mailbox and return the address it contains. + * + * TODO: PSYSR is a common register and should be + * accessed using locks. Since it is not possible + * to use locks immediately after a cold reset + * we are relying on the fact that after a cold + * reset all cpus will read the same WK field + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* --------------------------------------------------------------------- + * When bit PSYSR.WK indicates either "Wake by PPONR" or "Wake by GIC + * WakeRequest signal" then it is a warm boot. + * --------------------------------------------------------------------- + */ + mrs x2, mpidr_el1 + mov_imm x1, PWRC_BASE + str w2, [x1, #PSYSR_OFF] + ldr w2, [x1, #PSYSR_OFF] + ubfx w2, w2, #PSYSR_WK_SHIFT, #PSYSR_WK_WIDTH + cmp w2, #WKUP_PPONR + beq warm_reset + cmp w2, #WKUP_GICREQ + beq warm_reset + + /* Cold reset */ + mov x0, #0 + ret + +warm_reset: + /* --------------------------------------------------------------------- + * A mailbox is maintained in the trusted SRAM. It is flushed out of the + * caches after every update using normal memory so it is safe to read + * it here with SO attributes. + * --------------------------------------------------------------------- + */ + mov_imm x0, PLAT_ARM_TRUSTED_MAILBOX_BASE + ldr x0, [x0] + cbz x0, _panic_handler + ret + + /* --------------------------------------------------------------------- + * The power controller indicates this is a warm reset but the mailbox + * is empty. This should never happen! + * --------------------------------------------------------------------- + */ +_panic_handler: + no_ret plat_panic_handler +endfunc plat_get_my_entrypoint + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + mov_imm x1, MPIDR_AFFINITY_MASK + and x0, x0, x1 + cmp x0, #FVP_R_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on FVP_R. + * + * (ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER * FVP_R_MAX_PE_PER_CPU) + + * (CPUId * FVP_R_MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_R_MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- + */ +func plat_arm_calc_core_pos + /* + * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it + * look as if in a multi-threaded implementation. + */ + tst x0, #MPIDR_MT_MASK + lsl x3, x0, #MPIDR_AFFINITY_BITS + csel x3, x3, x0, eq + + /* Extract individual affinity fields from MPIDR */ + ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov x4, #FVP_R_MAX_CPUS_PER_CLUSTER + madd x1, x2, x4, x1 + mov x5, #FVP_R_MAX_PE_PER_CPU + madd x0, x1, x5, x0 + ret +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/fvp_r/fvp_r_io_storage.c b/plat/arm/board/fvp_r/fvp_r_io_storage.c new file mode 100644 index 000000000..630d93a10 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_io_storage.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* Semihosting filenames */ +#define TB_FW_CONFIG_NAME "fvp_tb_fw_config.dtb" +#define HW_CONFIG_NAME "hw_config.dtb" + +#if TRUSTED_BOARD_BOOT +#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" +#define TRUSTED_KEY_CERT_NAME "trusted_key.crt" +#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" +#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" +#define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" +#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" +#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" +#define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" +#endif /* TRUSTED_BOARD_BOOT */ + +/* IO devices */ +static const io_dev_connector_t *sh_dev_con; +static uintptr_t sh_dev_handle; + +static const io_file_spec_t sh_file_spec[] = { + [TB_FW_CONFIG_ID] = { + .path = TB_FW_CONFIG_NAME, + .mode = FOPEN_MODE_RB + }, + [HW_CONFIG_ID] = { + .path = HW_CONFIG_NAME, + .mode = FOPEN_MODE_RB + }, +#if TRUSTED_BOARD_BOOT + [TRUSTED_KEY_CERT_ID] = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [NON_TRUSTED_FW_KEY_CERT_ID] = { + .path = NT_FW_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB + }, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = { + .path = NT_FW_CONTENT_CERT_NAME, + .mode = FOPEN_MODE_RB + }, +#endif /* TRUSTED_BOARD_BOOT */ +}; + + +static int open_semihosting(const uintptr_t spec) +{ + int result; + uintptr_t local_image_handle; + + /* See if the file exists on semi-hosting.*/ + result = io_dev_init(sh_dev_handle, (uintptr_t)NULL); + if (result == 0) { + result = io_open(sh_dev_handle, spec, &local_image_handle); + if (result == 0) { + VERBOSE("Using Semi-hosting IO\n"); + io_close(local_image_handle); + } + } + return result; +} + +void plat_arm_io_setup(void) +{ + int io_result; + + io_result = arm_io_setup(); + if (io_result < 0) { + panic(); + } + + /* Register the additional IO devices on this platform */ + io_result = register_io_dev_sh(&sh_dev_con); + if (io_result < 0) { + panic(); + } + + /* Open connections to devices and cache the handles */ + io_result = io_dev_open(sh_dev_con, (uintptr_t)NULL, &sh_dev_handle); + if (io_result < 0) { + panic(); + } +} + +/* + * FVP_R provides semihosting as an alternative to load images + */ +int plat_arm_get_alt_image_source(unsigned int image_id, uintptr_t *dev_handle, + uintptr_t *image_spec) +{ + int result = open_semihosting((const uintptr_t)&sh_file_spec[image_id]); + + if (result == 0) { + *dev_handle = sh_dev_handle; + *image_spec = (uintptr_t)&sh_file_spec[image_id]; + } + + return result; +} diff --git a/plat/arm/board/fvp_r/fvp_r_private.h b/plat/arm/board/fvp_r/fvp_r_private.h new file mode 100644 index 000000000..48f6e891e --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_private.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_R_PRIVATE_H +#define FVP_R_PRIVATE_H + +#include + +/******************************************************************************* + * Function and variable prototypes + ******************************************************************************/ + +void fvp_config_setup(void); + +void fvp_interconnect_init(void); +void fvp_interconnect_enable(void); +void fvp_interconnect_disable(void); +void fvp_timer_init(void); + +#endif /* FVP_R_PRIVATE_H */ diff --git a/plat/arm/board/fvp_r/fvp_r_stack_protector.c b/plat/arm/board/fvp_r/fvp_r_stack_protector.c new file mode 100644 index 000000000..5922a9804 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_stack_protector.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#define RANDOM_CANARY_VALUE ((u_register_t) 8092347823957523895ULL) + +u_register_t plat_get_stack_protector_canary(void) +{ + /* + * Ideally, a random number should be returned instead of the + * combination of a timer's value and a compile-time constant. As the + * FVP_R does not have any random number generator, this is better than + * nothing but not necessarily really secure. + */ + return RANDOM_CANARY_VALUE ^ read_cntpct_el0(); +} + diff --git a/plat/arm/board/fvp_r/fvp_r_trusted_boot.c b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c new file mode 100644 index 000000000..f304e3e0a --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +/* + * Return the ROTPK hash in the following ASN.1 structure in DER format: + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DigestInfo ::= SEQUENCE { + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING + * } + */ +int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, + unsigned int *flags) +{ + return arm_get_rotpk_info(cookie, key_ptr, key_len, flags); +} + +/* + * Store a new non-volatile counter value. + * + * On some FVP_R versions, the non-volatile counters are read-only so this + * function will always fail. + * + * Return: 0 = success, Otherwise = error + */ +int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) +{ + const char *oid; + uintptr_t nv_ctr_addr; + + assert(cookie != NULL); + + oid = (const char *)cookie; + if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); + } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); + } else { + return 1; + } + + mmio_write_32(nv_ctr_addr, nv_ctr); + + /* + * If the FVP_R models a locked counter then its value cannot be updated + * and the above write operation has been silently ignored. + */ + return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1; +} diff --git a/plat/arm/board/fvp_r/include/plat.ld.S b/plat/arm/board/fvp_r/include/plat.ld.S new file mode 100644 index 000000000..e91a5a0f4 --- /dev/null +++ b/plat/arm/board/fvp_r/include/plat.ld.S @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_LD_S +#define PLAT_LD_S + +#include + +#endif /* PLAT_LD_S */ diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h new file mode 100644 index 000000000..458668190 --- /dev/null +++ b/plat/arm/board/fvp_r/include/platform_def.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include "../fvp_r_def.h" +#include +#include +#include + +#include +#include + + +#define NO_EL3 1 + +/* Required platform porting definitions */ +#define PLATFORM_CORE_COUNT (U(FVP_R_CLUSTER_COUNT) * \ + U(FVP_R_MAX_CPUS_PER_CLUSTER) * \ + U(FVP_R_MAX_PE_PER_CPU)) + +#define PLAT_NUM_PWR_DOMAINS (U(FVP_R_CLUSTER_COUNT) + \ + PLATFORM_CORE_COUNT + U(1)) + +#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2 + +/* + * Other platform porting definitions are provided by included headers + */ + +/* + * Required ARM standard platform porting definitions + */ +#define PLAT_ARM_CLUSTER_COUNT U(FVP_R_CLUSTER_COUNT) + +#define PLAT_ARM_DRAM1_BASE ULL(0x0) + +#define PLAT_ARM_TRUSTED_ROM_BASE UL(0x80000000) +#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x04000000) /* 64 MB */ + +#define PLAT_ARM_TRUSTED_SRAM_BASE UL(0x84000000) +#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */ + +#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x86000000) +#define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ + +/* virtual address used by dynamic mem_protect for chunk_base */ +#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) + +/* No SCP in FVP_R */ +#define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x0) + +#define PLAT_ARM_DRAM2_BASE ULL(0x080000000) +#define PLAT_ARM_DRAM2_SIZE UL(0x80000000) + +#define PLAT_HW_CONFIG_DTB_BASE ULL(0x12000000) +#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) + +#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ + PLAT_HW_CONFIG_DTB_BASE, \ + PLAT_HW_CONFIG_DTB_SIZE, \ + MT_MEMORY | MT_RO | MT_NS) +/* + * Load address of BL33 for this platform port + */ +#define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x8000000)) + +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if !USE_ROMLIB +# define PLAT_ARM_MMAP_ENTRIES 11 +# define MAX_XLAT_TABLES 5 +#else +# define PLAT_ARM_MMAP_ENTRIES 12 +# define MAX_XLAT_TABLES 6 +#endif + +/* + * These nominally reserve the last block of flash for PSCI MEM PROTECT flag, + * but no PSCI in FVP_R platform, so reserve nothing: + */ +#define PLAT_ARM_FLASH_IMAGE_BASE V2M_FLASH0_BASE +#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE 0 + +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#define PLAT_ARM_MAX_BL1_RW_SIZE UL(0xB000) + +/* + * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page + */ + +#if USE_ROMLIB +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000) +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000) +#define FVP_R_BL2_ROMLIB_OPTIMIZATION UL(0x6000) +#else +#define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0) +#define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0) +#define FVP_R_BL2_ROMLIB_OPTIMIZATION UL(0) +#endif + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#if TRUSTED_BOARD_BOOT +#if COT_DESC_IN_DTB +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1E000) - FVP_R_BL2_ROMLIB_OPTIMIZATION) +#else +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_R_BL2_ROMLIB_OPTIMIZATION) +#endif +#else +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x13000) - FVP_R_BL2_ROMLIB_OPTIMIZATION) +#endif + +/* + * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is + * calculated using the current BL31 PROGBITS debug size plus the sizes of + * BL2 and BL1-RW + */ +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) + +/* + * Size of cacheable stacks + */ +#if defined(IMAGE_BL1) +# if TRUSTED_BOARD_BOOT +# define PLATFORM_STACK_SIZE UL(0x1000) +# else +# define PLATFORM_STACK_SIZE UL(0x500) +# endif +#endif + +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/* Reserve the last block of flash for PSCI MEM PROTECT flag */ +#define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE +#define PLAT_ARM_FIP_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE +#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/* + * PL011 related constants + */ +#define PLAT_ARM_BOOT_UART_BASE V2M_IOFPGA_UART0_BASE +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ + +#define PLAT_ARM_RUN_UART_BASE V2M_IOFPGA_UART1_BASE +#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ + +#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE +#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ + +#define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE +#define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ + +/* CCI related constants */ +#define PLAT_FVP_R_CCI400_BASE UL(0xac090000) +#define PLAT_FVP_R_CCI400_CLUS0_SL_PORT 3 +#define PLAT_FVP_R_CCI400_CLUS1_SL_PORT 4 + +/* CCI-500/CCI-550 on Base platform */ +#define PLAT_FVP_R_CCI5XX_BASE UL(0xaa000000) +#define PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT 5 +#define PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT 6 + +/* CCN related constants. Only CCN 502 is currently supported */ +#define PLAT_ARM_CCN_BASE UL(0xae000000) +#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP 1, 5, 7, 11 + +/* System timer related constants */ +#define PLAT_ARM_NSTIMER_FRAME_ID U(1) + +/* Mailbox base address */ +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE + + +/* TrustZone controller related constants + * + * Currently only filters 0 and 2 are connected on Base FVP_R. + * Filter 0 : CPU clusters (no access to DRAM by default) + * Filter 1 : not connected + * Filter 2 : LCDs (access to VRAM allowed by default) + * Filter 3 : not connected + * Programming unconnected filters will have no effect at the + * moment. These filter could, however, be connected in future. + * So care should be taken not to configure the unused filters. + * + * Allow only non-secure access to all DRAM to supported devices. + * Give access to the CPUs and Virtio. Some devices + * would normally use the default ID so allow that too. + */ +#define PLAT_ARM_TZC_BASE UL(0xaa4a0000) +#define PLAT_ARM_TZC_FILTERS TZC_400_REGION_ATTR_FILTER_BIT(0) + +#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \ + TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_DEFAULT) | \ + TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_PCI) | \ + TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_AP) | \ + TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_VIRTIO) | \ + TZC_REGION_ACCESS_RDWR(FVP_R_NSAID_VIRTIO_OLD)) + +/* + * GIC related constants to cater for both GICv2 and GICv3 instances of an + * FVP_R. They could be overridden at runtime in case the FVP_R implements the + * legacy VE memory map. + */ +#define PLAT_ARM_GICD_BASE BASE_GICD_BASE +#define PLAT_ARM_GICR_BASE BASE_GICR_BASE +#define PLAT_ARM_GICC_BASE BASE_GICC_BASE + +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) + +#define PLAT_SP_PRI PLAT_RAS_PRI + +/* + * Physical and virtual address space limits for MPU in AARCH64 & AARCH32 modes + */ +#ifdef __aarch64__ +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) +#else +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) +#endif + +#define ARM_SOC_CONTINUATION_SHIFT U(24) +#define ARM_SOC_IDENTIFICATION_SHIFT U(16) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk new file mode 100644 index 000000000..1387ae711 --- /dev/null +++ b/plat/arm/board/fvp_r/platform.mk @@ -0,0 +1,131 @@ +# +# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Only aarch64 ARCH supported for FVP_R +ARCH := aarch64 + +# Override to exclude BL2, BL2U, BL31, and BL33 for FVP_R +override NEED_BL2 := no +override NEED_BL2U := no +override NEED_BL31 := no +override NEED_BL33 := no + +# Default cluster count for FVP_R +FVP_R_CLUSTER_COUNT := 2 + +# Default number of CPUs per cluster on FVP_R +FVP_R_MAX_CPUS_PER_CLUSTER := 4 + +# Default number of threads per CPU on FVP_R +FVP_R_MAX_PE_PER_CPU := 1 + +# Need to revisit this for FVP_R +FVP_R_DT_PREFIX := fvp-base-gicv3-psci + +# Pass FVP_R_CLUSTER_COUNT to the build system. +$(eval $(call add_define,FVP_R_CLUSTER_COUNT)) + +# Pass FVP_R_MAX_CPUS_PER_CLUSTER to the build system. +$(eval $(call add_define,FVP_R_MAX_CPUS_PER_CLUSTER)) + +# Pass FVP_R_MAX_PE_PER_CPU to the build system. +$(eval $(call add_define,FVP_R_MAX_PE_PER_CPU)) + +# Sanity check the cluster count and if FVP_R_CLUSTER_COUNT <= 2, +# choose the CCI driver , else the CCN driver +ifeq ($(FVP_R_CLUSTER_COUNT), 0) +$(error "Incorrect cluster count specified for FVP_R port") +else ifeq ($(FVP_R_CLUSTER_COUNT),$(filter $(FVP_R_CLUSTER_COUNT),1 2)) +FVP_R_INTERCONNECT_DRIVER := FVP_R_CCI +else +FVP_R_INTERCONNECT_DRIVER := FVP_R_CCN +endif + +$(eval $(call add_define,FVP_R_INTERCONNECT_DRIVER)) + +ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCI) +FVP_R_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c +else ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCN) +FVP_R_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \ + plat/arm/common/arm_ccn.c +else +$(error "Incorrect CCN driver chosen on FVP_R port") +endif + +PLAT_INCLUDES := -Iplat/arm/board/fvp_r/include + +PLAT_BL_COMMON_SOURCES := plat/arm/board/fvp_r/fvp_r_common.c + +FVP_R_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S + +# select a different set of CPU files, depending on whether we compile for +# hardware assisted coherency cores or not +ifeq (${HW_ASSISTED_COHERENCY}, 0) +# Cores used without DSU +# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S +else +# Cores used with DSU only +# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S +endif + +BL1_SOURCES += drivers/arm/sp805/sp805.c \ + drivers/delay_timer/delay_timer.c \ + drivers/io/io_semihosting.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + plat/arm/board/fvp_r/fvp_r_helpers.S \ + plat/arm/board/fvp_r/fvp_r_bl1_setup.c \ + plat/arm/board/fvp_r/fvp_r_err.c \ + plat/arm/board/fvp_r/fvp_r_io_storage.c \ + ${FVP_R_CPU_LIBS} \ + ${FVP_R_INTERCONNECT_SOURCES} + +ifeq (${USE_SP804_TIMER},1) +BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c +else +BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c +endif + +# Enable Activity Monitor Unit extensions by default +ENABLE_AMU := 1 + +ifneq (${ENABLE_STACK_PROTECTOR},0) +PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp_r/fvp_r_stack_protector.c +endif + +ifeq (${ARCH},aarch32) + NEED_BL32 := yes +endif + +ifneq (${BL2_AT_EL3}, 0) + override BL1_SOURCES = +endif + +# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) +ifdef UNIX_MK +FVP_R_HW_CONFIG_DTS := fdts/${FVP_R_DT_PREFIX}.dts +FDT_SOURCES += $(addprefix plat/arm/board/fvp_r/fdts/, \ + ${PLAT}_fw_config.dts \ + ${PLAT}_nt_fw_config.dts \ + ) + +FVP_R_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb +FVP_R_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb + +# Add the FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_FW_CONFIG},--fw-config,${FVP_R_FW_CONFIG})) +# Add the NT_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_NT_FW_CONFIG},--nt-fw-config,${FVP_R_NT_FW_CONFIG})) + +FDT_SOURCES += ${FVP_R_HW_CONFIG_DTS} +$(eval FVP_R_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_R_HW_CONFIG_DTS))) + +# Add the HW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_HW_CONFIG},--hw-config,${FVP_R_HW_CONFIG})) +endif + +include plat/arm/board/common/board_common.mk +include plat/arm/common/arm_common.mk -- cgit v1.2.3 From 5fb061e761ee98d6ba1938d87efcc26a29ef0a87 Mon Sep 17 00:00:00 2001 From: Gary Morrison Date: Wed, 27 Jan 2021 13:08:47 -0600 Subject: chore: fvp_r: Initial No-EL3 and MPU Implementation For v8-R64, especially R82, creating code to run BL1 at EL2, using MPU. Signed-off-by: Gary Morrison Change-Id: I439ac3915b982ad1e61d24365bdd1584b3070425 --- bl1/bl1.mk | 10 +- docs/components/xlat-tables-lib-v2-design.rst | 51 ++- include/arch/aarch64/arch.h | 5 + include/arch/aarch64/el2_common_macros.S | 448 ++++++++++++++++++++++ include/plat/arm/board/common/v2m_def.h | 29 +- include/plat/arm/common/arm_def.h | 37 +- lib/xlat_mpu/aarch64/enable_mpu.S | 53 +++ lib/xlat_mpu/aarch64/xlat_mpu_arch.c | 69 ++++ lib/xlat_mpu/ro_xlat_mpu.mk | 14 + lib/xlat_mpu/xlat_mpu.h | 22 ++ lib/xlat_mpu/xlat_mpu.mk | 19 + lib/xlat_mpu/xlat_mpu_context.c | 65 ++++ lib/xlat_mpu/xlat_mpu_core.c | 408 ++++++++++++++++++++ lib/xlat_mpu/xlat_mpu_private.h | 103 +++++ lib/xlat_mpu/xlat_mpu_utils.c | 71 ++++ lib/xlat_tables/aarch64/xlat_tables.c | 4 +- plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c | 35 ++ plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c | 96 +++++ plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S | 70 ++++ plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S | 120 ++++++ plat/arm/board/fvp_r/fvp_r_bl1_main.c | 213 ++++++++++ plat/arm/board/fvp_r/fvp_r_bl1_setup.c | 82 ++++ plat/arm/board/fvp_r/fvp_r_common.c | 78 +++- plat/arm/board/fvp_r/fvp_r_context.S | 17 + plat/arm/board/fvp_r/fvp_r_context_mgmt.c | 28 ++ plat/arm/board/fvp_r/fvp_r_debug.S | 46 +++ plat/arm/board/fvp_r/fvp_r_def.h | 22 +- plat/arm/board/fvp_r/fvp_r_misc_helpers.S | 32 ++ plat/arm/board/fvp_r/fvp_r_pauth_helpers.S | 59 +++ plat/arm/board/fvp_r/fvp_r_stack_protector.c | 2 +- plat/arm/board/fvp_r/fvp_r_trusted_boot.c | 8 +- plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h | 28 ++ plat/arm/board/fvp_r/include/platform_def.h | 57 ++- plat/arm/board/fvp_r/platform.mk | 19 +- plat/arm/common/arm_bl1_setup.c | 4 +- plat/arm/common/arm_common.mk | 12 +- 36 files changed, 2357 insertions(+), 79 deletions(-) create mode 100644 include/arch/aarch64/el2_common_macros.S create mode 100644 lib/xlat_mpu/aarch64/enable_mpu.S create mode 100644 lib/xlat_mpu/aarch64/xlat_mpu_arch.c create mode 100644 lib/xlat_mpu/ro_xlat_mpu.mk create mode 100644 lib/xlat_mpu/xlat_mpu.h create mode 100644 lib/xlat_mpu/xlat_mpu.mk create mode 100644 lib/xlat_mpu/xlat_mpu_context.c create mode 100644 lib/xlat_mpu/xlat_mpu_core.c create mode 100644 lib/xlat_mpu/xlat_mpu_private.h create mode 100644 lib/xlat_mpu/xlat_mpu_utils.c create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S create mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_main.c create mode 100644 plat/arm/board/fvp_r/fvp_r_context.S create mode 100644 plat/arm/board/fvp_r/fvp_r_context_mgmt.c create mode 100644 plat/arm/board/fvp_r/fvp_r_debug.S create mode 100644 plat/arm/board/fvp_r/fvp_r_misc_helpers.S create mode 100644 plat/arm/board/fvp_r/fvp_r_pauth_helpers.S create mode 100644 plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h diff --git a/bl1/bl1.mk b/bl1/bl1.mk index d11b4ab0e..8f44151da 100644 --- a/bl1/bl1.mk +++ b/bl1/bl1.mk @@ -1,15 +1,17 @@ # -# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -BL1_SOURCES += bl1/bl1_main.c \ - bl1/${ARCH}/bl1_arch_setup.c \ +ifneq (${PLAT},fvp_r) +BL1_SOURCES += bl1/${ARCH}/bl1_arch_setup.c \ bl1/${ARCH}/bl1_context_mgmt.c \ bl1/${ARCH}/bl1_entrypoint.S \ bl1/${ARCH}/bl1_exceptions.S \ - lib/cpus/${ARCH}/cpu_helpers.S \ + bl1/bl1_main.c +endif +BL1_SOURCES += lib/cpus/${ARCH}/cpu_helpers.S \ lib/cpus/errata_report.c \ lib/el3_runtime/${ARCH}/context_mgmt.c \ plat/common/plat_bl1_common.c \ diff --git a/docs/components/xlat-tables-lib-v2-design.rst b/docs/components/xlat-tables-lib-v2-design.rst index af5151f70..cac32f587 100644 --- a/docs/components/xlat-tables-lib-v2-design.rst +++ b/docs/components/xlat-tables-lib-v2-design.rst @@ -10,7 +10,7 @@ required Translation Lookaside Buffer (TLB) maintenance operations. More specifically, some use cases that this library aims to support are: #. Statically allocate translation tables and populate them (at run-time) based - on a description of the memory layout. The memory layout is typically + upon a description of the memory layout. The memory layout is typically provided by the platform port as a list of memory regions; #. Support for generating translation tables pertaining to a different @@ -26,22 +26,28 @@ More specifically, some use cases that this library aims to support are: #. Support for changing memory attributes of memory regions at run-time. -About version 1 and version 2 ------------------------------ +About version 1, version 2 and MPU libraries +-------------------------------------------- This document focuses on version 2 of the library, whose sources are available in the ``lib/xlat_tables_v2`` directory. Version 1 of the library can still be found in ``lib/xlat_tables`` directory but it is less flexible and doesn't -support dynamic mapping. Although potential bug fixes will be applied to both -versions, future features enhancements will focus on version 2 and might not be -back-ported to version 1. Therefore, it is recommended to use version 2, -especially for new platform ports. - -However, please note that version 2 is still in active development and is not -considered stable yet. Hence, compatibility breaks might be introduced. +support dynamic mapping. ``lib/xlat_mpu``, which configures Arm's MPU +equivalently, is also addressed here. The ``lib/xlat_mpu`` is experimental, +meaning that its API may change. It currently strives for consistency and +code-reuse with xlat_tables_v2. Future versions may be more MPU-specific (e.g., +removing all mentions of virtual addresses). Although potential bug fixes will +be applied to all versions of the xlat_* libs, future feature enhancements will +focus on version 2 and might not be back-ported to version 1 and MPU versions. +Therefore, it is recommended to use version 2, especially for new platform +ports (unless the platform uses an MPU). + +However, please note that version 2 and the MPU version are still in active +development and is not considered stable yet. Hence, compatibility breaks might +be introduced. From this point onwards, this document will implicitly refer to version 2 of the -library. +library, unless stated otherwise. Design concepts and interfaces @@ -102,6 +108,16 @@ The region's granularity is an optional field; if it is not specified the library will choose the mapping granularity for this region as it sees fit (more details can be found in `The memory mapping algorithm`_ section below). +The MPU library also uses ``struct mmap_region`` to specify translations, but +the MPU's translations are limited to specification of valid addresses and +access permissions. If the requested virtual and physical addresses mismatch +the system will panic. Being register-based for deterministic memory-reference +timing, the MPU hardware does not involve memory-resident translation tables. + +Currently, the MPU library is also limited to MPU translation at EL2 with no +MMU translation at other ELs. These limitations, however, are expected to be +overcome in future library versions. + Translation Context ~~~~~~~~~~~~~~~~~~~ @@ -215,7 +231,8 @@ future. The ``MAP_REGION()`` and ``MAP_REGION_FLAT()`` macros do not allow specifying a mapping granularity, which leaves the library implementation free to choose it. However, in cases where a specific granularity is required, the -``MAP_REGION2()`` macro might be used instead. +``MAP_REGION2()`` macro might be used instead. Using ``MAP_REGION_FLAT()`` only +to define regions for the MPU library is strongly recommended. As explained earlier in this document, when the dynamic mapping feature is disabled, there is no notion of dynamic regions. Conceptually, there are only @@ -374,6 +391,9 @@ entries in the translation tables are checked to ensure consistency. Please refer to the comments in the source code of the core module for more details about the sorting algorithm in use. +This mapping algorithm does not apply to the MPU library, since the MPU hardware +directly maps regions by "base" and "limit" (bottom and top) addresses. + TLB maintenance operations ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -390,6 +410,11 @@ address translation at reset [#tlb-reset-ref]_. Therefore, the TLBs invalidation is deferred to the ``enable_mmu*()`` family of functions, just before the MMU is turned on. +Regarding enabling and disabling memory management, for the MPU library, to +reduce confusion, calls to enable or disable the MPU use ``mpu`` in their names +in place of ``mmu``. For example, the ``enable_mmu_el2()`` call is changed to +``enable_mpu_el2()``. + TLB invalidation is not required when adding dynamic regions either. Dynamic regions are not allowed to overlap existing memory region. Therefore, if the dynamic mapping request is deemed legitimate, it automatically concerns memory @@ -412,6 +437,6 @@ mapping cannot be cached in the TLBs. -------------- -*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.* .. |Alignment Example| image:: ../resources/diagrams/xlat_align.png diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index d260ecf45..1b3ae0221 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -522,13 +522,18 @@ #define VTTBR_BADDR_SHIFT U(0) /* HCR definitions */ +#define HCR_RESET_VAL ULL(0x0) #define HCR_AMVOFFEN_BIT (ULL(1) << 51) +#define HCR_TEA_BIT (ULL(1) << 47) #define HCR_API_BIT (ULL(1) << 41) #define HCR_APK_BIT (ULL(1) << 40) #define HCR_E2H_BIT (ULL(1) << 34) +#define HCR_HCD_BIT (ULL(1) << 29) #define HCR_TGE_BIT (ULL(1) << 27) #define HCR_RW_SHIFT U(31) #define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT) +#define HCR_TWE_BIT (ULL(1) << 14) +#define HCR_TWI_BIT (ULL(1) << 13) #define HCR_AMO_BIT (ULL(1) << 5) #define HCR_IMO_BIT (ULL(1) << 4) #define HCR_FMO_BIT (ULL(1) << 3) diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S new file mode 100644 index 000000000..c57a1ec3c --- /dev/null +++ b/include/arch/aarch64/el2_common_macros.S @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EL2_COMMON_MACROS_S +#define EL2_COMMON_MACROS_S + +#include +#include +#include +#include + +#include + + /* + * Helper macro to initialise system registers at EL2. + */ + .macro el2_arch_init_common + + /* --------------------------------------------------------------------- + * SCTLR_EL2 has already been initialised - read current value before + * modifying. + * + * SCTLR_EL2.I: Enable the instruction cache. + * + * SCTLR_EL2.SA: Enable Stack Alignment check. A SP alignment fault + * exception is generated if a load or store instruction executed at + * EL2 uses the SP as the base address and the SP is not aligned to a + * 16-byte boundary. + * + * SCTLR_EL2.A: Enable Alignment fault checking. All instructions that + * load or store one or more registers have an alignment check that the + * address being accessed is aligned to the size of the data element(s) + * being accessed. + * --------------------------------------------------------------------- + */ + mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT) + mrs x0, sctlr_el2 + orr x0, x0, x1 + msr sctlr_el2, x0 + isb + + /* --------------------------------------------------------------------- + * Initialise HCR_EL2, setting all fields rather than relying on HW. + * All fields are architecturally UNKNOWN on reset. The following fields + * do not change during the TF lifetime. The remaining fields are set to + * zero here but are updated ahead of transitioning to a lower EL in the + * function cm_init_context_common(). + * + * HCR_EL2.TWE: Set to zero so that execution of WFE instructions at + * EL2, EL1 and EL0 are not trapped to EL2. + * + * HCR_EL2.TWI: Set to zero so that execution of WFI instructions at + * EL2, EL1 and EL0 are not trapped to EL2. + * + * HCR_EL2.HCD: Set to zero to enable HVC calls at EL1 and above, + * from both Security states and both Execution states. + * + * HCR_EL2.TEA: Set to one to route External Aborts and SError + * Interrupts to EL2 when executing at any EL. + * + * HCR_EL2.{API,APK}: For Armv8.3 pointer authentication feature, + * disable traps to EL2 when accessing key registers or using + * pointer authentication instructions from lower ELs. + * --------------------------------------------------------------------- + */ + mov_imm x0, ((HCR_RESET_VAL | HCR_TEA_BIT) \ + & ~(HCR_TWE_BIT | HCR_TWI_BIT | HCR_HCD_BIT)) +#if CTX_INCLUDE_PAUTH_REGS + /* + * If the pointer authentication registers are saved during world + * switches, enable pointer authentication everywhere, as it is safe to + * do so. + */ + orr x0, x0, #(HCR_API_BIT | HCR_APK_BIT) +#endif /* CTX_INCLUDE_PAUTH_REGS */ + msr hcr_el2, x0 + + /* --------------------------------------------------------------------- + * Initialise MDCR_EL2, setting all fields rather than relying on + * hw. Some fields are architecturally UNKNOWN on reset. + * + * MDCR_EL2.SDD: Set to one to disable AArch64 Secure self-hosted + * debug. Debug exceptions, other than Breakpoint Instruction + * exceptions, are disabled from all ELs in Secure state. + * + * MDCR_EL2.TDOSA: Set to zero so that EL2 and EL2 System register + * access to the powerdown debug registers do not trap to EL2. + * + * MDCR_EL2.TDA: Set to zero to allow EL0, EL1 and EL2 access to the + * debug registers, other than those registers that are controlled by + * MDCR_EL2.TDOSA. + * + * MDCR_EL2.TPM: Set to zero so that EL0, EL1, and EL2 System + * register accesses to all Performance Monitors registers do not trap + * to EL2. + * + * MDCR_EL2.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 + * is prohibited in Secure state. This bit is RES0 in versions of the + * architecture with FEAT_PMUv3p5 not implemented, setting it to 1 + * doesn't have any effect on them. + * + * MDCR_EL2.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 + * is prohibited in EL2. This bit is RES0 in versions of the + * architecture with FEAT_PMUv3p7 not implemented, setting it to 1 + * doesn't have any effect on them. + * + * MDCR_EL2.SPME: Set to zero so that event counting by the program- + * mable counters PMEVCNTR_EL0 is prohibited in Secure state. If + * ARMv8.2 Debug is not implemented this bit does not have any effect + * on the counters unless there is support for the implementation + * defined authentication interface + * ExternalSecureNoninvasiveDebugEnabled(). + * --------------------------------------------------------------------- + */ + mov_imm x0, ((MDCR_EL2_RESET_VAL | MDCR_SDD_BIT | \ + MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \ + MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \ + MDCR_TDA_BIT | MDCR_TPM_BIT)) + + msr mdcr_el2, x0 + + /* --------------------------------------------------------------------- + * Initialise PMCR_EL0 setting all fields rather than relying + * on hw. Some fields are architecturally UNKNOWN on reset. + * + * PMCR_EL0.LP: Set to one so that event counter overflow, that + * is recorded in PMOVSCLR_EL0[0-30], occurs on the increment + * that changes PMEVCNTR_EL0[63] from 1 to 0, when ARMv8.5-PMU + * is implemented. This bit is RES0 in versions of the architecture + * earlier than ARMv8.5, setting it to 1 doesn't have any effect + * on them. + * + * PMCR_EL0.LC: Set to one so that cycle counter overflow, that + * is recorded in PMOVSCLR_EL0[31], occurs on the increment + * that changes PMCCNTR_EL0[63] from 1 to 0. + * + * PMCR_EL0.DP: Set to one so that the cycle counter, + * PMCCNTR_EL0 does not count when event counting is prohibited. + * + * PMCR_EL0.X: Set to zero to disable export of events. + * + * PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0 + * counts on every clock cycle. + * --------------------------------------------------------------------- + */ + mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_LP_BIT | \ + PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT) & \ + ~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT)) + + msr pmcr_el0, x0 + + /* --------------------------------------------------------------------- + * Enable External Aborts and SError Interrupts now that the exception + * vectors have been setup. + * --------------------------------------------------------------------- + */ + msr daifclr, #DAIF_ABT_BIT + + /* --------------------------------------------------------------------- + * Initialise CPTR_EL2, setting all fields rather than relying on hw. + * All fields are architecturally UNKNOWN on reset. + * + * CPTR_EL2.TCPAC: Set to zero so that any accesses to CPACR_EL1 do + * not trap to EL2. + * + * CPTR_EL2.TTA: Set to zero so that System register accesses to the + * trace registers do not trap to EL2. + * + * CPTR_EL2.TFP: Set to zero so that accesses to the V- or Z- registers + * by Advanced SIMD, floating-point or SVE instructions (if implemented) + * do not trap to EL2. + */ + + mov_imm x0, (CPTR_EL2_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT)) + msr cptr_el2, x0 + + /* + * If Data Independent Timing (DIT) functionality is implemented, + * always enable DIT in EL2 + */ + mrs x0, id_aa64pfr0_el1 + ubfx x0, x0, #ID_AA64PFR0_DIT_SHIFT, #ID_AA64PFR0_DIT_LENGTH + cmp x0, #ID_AA64PFR0_DIT_SUPPORTED + bne 1f + mov x0, #DIT_BIT + msr DIT, x0 +1: + .endm + +/* ----------------------------------------------------------------------------- + * This is the super set of actions that need to be performed during a cold boot + * or a warm boot in EL2. This code is shared by BL1 and BL31. + * + * This macro will always perform reset handling, architectural initialisations + * and stack setup. The rest of the actions are optional because they might not + * be needed, depending on the context in which this macro is called. This is + * why this macro is parameterised ; each parameter allows to enable/disable + * some actions. + * + * _init_sctlr: + * Whether the macro needs to initialise SCTLR_EL2, including configuring + * the endianness of data accesses. + * + * _warm_boot_mailbox: + * Whether the macro needs to detect the type of boot (cold/warm). The + * detection is based on the platform entrypoint address : if it is zero + * then it is a cold boot, otherwise it is a warm boot. In the latter case, + * this macro jumps on the platform entrypoint address. + * + * _secondary_cold_boot: + * Whether the macro needs to identify the CPU that is calling it: primary + * CPU or secondary CPU. The primary CPU will be allowed to carry on with + * the platform initialisations, while the secondaries will be put in a + * platform-specific state in the meantime. + * + * If the caller knows this macro will only be called by the primary CPU + * then this parameter can be defined to 0 to skip this step. + * + * _init_memory: + * Whether the macro needs to initialise the memory. + * + * _init_c_runtime: + * Whether the macro needs to initialise the C runtime environment. + * + * _exception_vectors: + * Address of the exception vectors to program in the VBAR_EL2 register. + * + * _pie_fixup_size: + * Size of memory region to fixup Global Descriptor Table (GDT). + * + * A non-zero value is expected when firmware needs GDT to be fixed-up. + * + * ----------------------------------------------------------------------------- + */ + .macro el2_entrypoint_common \ + _init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \ + _init_memory, _init_c_runtime, _exception_vectors, \ + _pie_fixup_size + + .if \_init_sctlr + /* ------------------------------------------------------------- + * This is the initialisation of SCTLR_EL2 and so must ensure + * that all fields are explicitly set rather than relying on hw. + * Some fields reset to an IMPLEMENTATION DEFINED value and + * others are architecturally UNKNOWN on reset. + * + * SCTLR.EE: Set the CPU endianness before doing anything that + * might involve memory reads or writes. Set to zero to select + * Little Endian. + * + * SCTLR_EL2.WXN: For the EL2 translation regime, this field can + * force all memory regions that are writeable to be treated as + * XN (Execute-never). Set to zero so that this control has no + * effect on memory access permissions. + * + * SCTLR_EL2.SA: Set to zero to disable Stack Alignment check. + * + * SCTLR_EL2.A: Set to zero to disable Alignment fault checking. + * + * SCTLR.DSSBS: Set to zero to disable speculation store bypass + * safe behaviour upon exception entry to EL2. + * ------------------------------------------------------------- + */ + mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \ + | SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT)) + msr sctlr_el2, x0 + isb + .endif /* _init_sctlr */ + +#if DISABLE_MTPMU + bl mtpmu_disable +#endif + + .if \_warm_boot_mailbox + /* ------------------------------------------------------------- + * This code will be executed for both warm and cold resets. + * Now is the time to distinguish between the two. + * Query the platform entrypoint address and if it is not zero + * then it means it is a warm boot so jump to this address. + * ------------------------------------------------------------- + */ + bl plat_get_my_entrypoint + cbz x0, do_cold_boot + br x0 + + do_cold_boot: + .endif /* _warm_boot_mailbox */ + + .if \_pie_fixup_size +#if ENABLE_PIE + /* + * ------------------------------------------------------------ + * If PIE is enabled fixup the Global descriptor Table only + * once during primary core cold boot path. + * + * Compile time base address, required for fixup, is calculated + * using "pie_fixup" label present within first page. + * ------------------------------------------------------------ + */ + pie_fixup: + ldr x0, =pie_fixup + and x0, x0, #~(PAGE_SIZE_MASK) + mov_imm x1, \_pie_fixup_size + add x1, x1, x0 + bl fixup_gdt_reloc +#endif /* ENABLE_PIE */ + .endif /* _pie_fixup_size */ + + /* --------------------------------------------------------------------- + * Set the exception vectors. + * --------------------------------------------------------------------- + */ + adr x0, \_exception_vectors + msr vbar_el2, x0 + isb + + /* --------------------------------------------------------------------- + * It is a cold boot. + * Perform any processor specific actions upon reset e.g. cache, TLB + * invalidations etc. + * --------------------------------------------------------------------- + */ + bl reset_handler + + el2_arch_init_common + + .if \_secondary_cold_boot + /* ------------------------------------------------------------- + * Check if this is a primary or secondary CPU cold boot. + * The primary CPU will set up the platform while the + * secondaries are placed in a platform-specific state until the + * primary CPU performs the necessary actions to bring them out + * of that state and allows entry into the OS. + * ------------------------------------------------------------- + */ + bl plat_is_my_cpu_primary + cbnz w0, do_primary_cold_boot + + /* This is a cold boot on a secondary CPU */ + bl plat_secondary_cold_boot_setup + /* plat_secondary_cold_boot_setup() is not supposed to return */ + bl el2_panic + do_primary_cold_boot: + .endif /* _secondary_cold_boot */ + + /* --------------------------------------------------------------------- + * Initialize memory now. Secondary CPU initialization won't get to this + * point. + * --------------------------------------------------------------------- + */ + + .if \_init_memory + bl platform_mem_init + .endif /* _init_memory */ + + /* --------------------------------------------------------------------- + * Init C runtime environment: + * - Zero-initialise the NOBITS sections. There are 2 of them: + * - the .bss section; + * - the coherent memory section (if any). + * - Relocate the data section from ROM to RAM, if required. + * --------------------------------------------------------------------- + */ + .if \_init_c_runtime + adrp x0, __BSS_START__ + add x0, x0, :lo12:__BSS_START__ + + adrp x1, __BSS_END__ + add x1, x1, :lo12:__BSS_END__ + sub x1, x1, x0 + bl zeromem + +#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM) + adrp x0, __DATA_RAM_START__ + add x0, x0, :lo12:__DATA_RAM_START__ + adrp x1, __DATA_ROM_START__ + add x1, x1, :lo12:__DATA_ROM_START__ + adrp x2, __DATA_RAM_END__ + add x2, x2, :lo12:__DATA_RAM_END__ + sub x2, x2, x0 + bl memcpy16 +#endif + .endif /* _init_c_runtime */ + + /* --------------------------------------------------------------------- + * Use SP_EL0 for the C runtime stack. + * --------------------------------------------------------------------- + */ + msr spsel, #0 + + /* --------------------------------------------------------------------- + * Allocate a stack whose memory will be marked as Normal-IS-WBWA when + * the MMU is enabled. There is no risk of reading stale stack memory + * after enabling the MMU as only the primary CPU is running at the + * moment. + * --------------------------------------------------------------------- + */ + bl plat_set_my_stack + +#if STACK_PROTECTOR_ENABLED + .if \_init_c_runtime + bl update_stack_protector_canary + .endif /* _init_c_runtime */ +#endif + .endm + + .macro apply_at_speculative_wa +#if ERRATA_SPECULATIVE_AT + /* + * Explicitly save x30 so as to free up a register and to enable + * branching and also, save x29 which will be used in the called + * function + */ + stp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29] + bl save_and_update_ptw_el1_sys_regs + ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29] +#endif + .endm + + .macro restore_ptw_el1_sys_regs +#if ERRATA_SPECULATIVE_AT + /* ----------------------------------------------------------- + * In case of ERRATA_SPECULATIVE_AT, must follow below order + * to ensure that page table walk is not enabled until + * restoration of all EL1 system registers. TCR_EL1 register + * should be updated at the end which restores previous page + * table walk setting of stage1 i.e.(TCR_EL1.EPDx) bits. ISB + * ensures that CPU does below steps in order. + * + * 1. Ensure all other system registers are written before + * updating SCTLR_EL1 using ISB. + * 2. Restore SCTLR_EL1 register. + * 3. Ensure SCTLR_EL1 written successfully using ISB. + * 4. Restore TCR_EL1 register. + * ----------------------------------------------------------- + */ + isb + ldp x28, x29, [sp, #CTX_EL1_SYSREGS_OFFSET + CTX_SCTLR_EL1] + msr sctlr_el1, x28 + isb + msr tcr_el1, x29 +#endif + .endm + +#endif /* EL2_COMMON_MACROS_S */ diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h index 6a6979c9c..cb11dac47 100644 --- a/include/plat/arm/board/common/v2m_def.h +++ b/include/plat/arm/board/common/v2m_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,13 @@ #include +/* Base address of all V2M */ +#ifdef PLAT_V2M_OFFSET +#define V2M_OFFSET PLAT_V2M_OFFSET +#else +#define V2M_OFFSET UL(0) +#endif + /* V2M motherboard system registers & offsets */ #define V2M_SYSREGS_BASE UL(0x1c010000) #define V2M_SYS_ID UL(0x0) @@ -69,18 +76,18 @@ /* NOR Flash */ -#define V2M_FLASH0_BASE UL(0x08000000) +#define V2M_FLASH0_BASE (V2M_OFFSET + UL(0x08000000)) #define V2M_FLASH0_SIZE UL(0x04000000) -#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */ +#define V2M_FLASH_BLOCK_SIZE UL(0x00040000) /* 256 KB */ -#define V2M_IOFPGA_BASE UL(0x1c000000) +#define V2M_IOFPGA_BASE (V2M_OFFSET + UL(0x1c000000)) #define V2M_IOFPGA_SIZE UL(0x03000000) /* PL011 UART related constants */ -#define V2M_IOFPGA_UART0_BASE UL(0x1c090000) -#define V2M_IOFPGA_UART1_BASE UL(0x1c0a0000) -#define V2M_IOFPGA_UART2_BASE UL(0x1c0b0000) -#define V2M_IOFPGA_UART3_BASE UL(0x1c0c0000) +#define V2M_IOFPGA_UART0_BASE (V2M_OFFSET + UL(0x1c090000)) +#define V2M_IOFPGA_UART1_BASE (V2M_OFFSET + UL(0x1c0a0000)) +#define V2M_IOFPGA_UART2_BASE (V2M_OFFSET + UL(0x1c0b0000)) +#define V2M_IOFPGA_UART3_BASE (V2M_OFFSET + UL(0x1c0c0000)) #define V2M_IOFPGA_UART0_CLK_IN_HZ 24000000 #define V2M_IOFPGA_UART1_CLK_IN_HZ 24000000 @@ -88,11 +95,11 @@ #define V2M_IOFPGA_UART3_CLK_IN_HZ 24000000 /* SP804 timer related constants */ -#define V2M_SP804_TIMER0_BASE UL(0x1C110000) -#define V2M_SP804_TIMER1_BASE UL(0x1C120000) +#define V2M_SP804_TIMER0_BASE (V2M_OFFSET + UL(0x1C110000)) +#define V2M_SP804_TIMER1_BASE (V2M_OFFSET + UL(0x1C120000)) /* SP810 controller */ -#define V2M_SP810_BASE UL(0x1c020000) +#define V2M_SP810_BASE (V2M_OFFSET + UL(0x1c020000)) #define V2M_SP810_CTRL_TIM0_SEL BIT_32(15) #define V2M_SP810_CTRL_TIM1_SEL BIT_32(17) #define V2M_SP810_CTRL_TIM2_SEL BIT_32(19) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 9d47b903d..08f7ff980 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -58,12 +58,11 @@ #define ARM_TRUSTED_DRAM_ID 1 #define ARM_DRAM_ID 2 -/* The first 4KB of Trusted SRAM are used as shared memory */ -#ifdef __PLAT_ARM_TRUSTED_SRAM_BASE__ +#ifdef PLAT_ARM_TRUSTED_SRAM_BASE #define ARM_TRUSTED_SRAM_BASE PLAT_ARM_TRUSTED_SRAM_BASE #else #define ARM_TRUSTED_SRAM_BASE UL(0x04000000) -#endif /* __PLAT_ARM_TRUSTED_SRAM_BASE__ */ +#endif /* PLAT_ARM_TRUSTED_SRAM_BASE */ #define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE #define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */ @@ -154,11 +153,11 @@ ARM_TZC_DRAM1_SIZE) #define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ ARM_NS_DRAM1_SIZE - 1U) -#ifdef __PLAT_ARM_DRAM1_BASE__ +#ifdef PLAT_ARM_DRAM1_BASE #define ARM_DRAM1_BASE PLAT_ARM_DRAM1_BASE #else #define ARM_DRAM1_BASE ULL(0x80000000) -#endif /* __PLAT_ARM_DRAM1_BASE__ */ +#endif /* PLAT_ARM_DRAM1_BASE */ #define ARM_DRAM1_SIZE ULL(0x80000000) #define ARM_DRAM1_END (ARM_DRAM1_BASE + \ @@ -321,16 +320,44 @@ ARM_BL_REGIONS) /* Memory mapped Generic timer interfaces */ +#ifdef PLAT_ARM_SYS_CNTCTL_BASE +#define ARM_SYS_CNTCTL_BASE PLAT_ARM_SYS_CNTCTL_BASE +#else #define ARM_SYS_CNTCTL_BASE UL(0x2a430000) +#endif + +#ifdef PLAT_ARM_SYS_CNTREAD_BASE +#define ARM_SYS_CNTREAD_BASE PLAT_ARM_SYS_CNTREAD_BASE +#else #define ARM_SYS_CNTREAD_BASE UL(0x2a800000) +#endif + +#ifdef PLAT_ARM_SYS_TIMCTL_BASE +#define ARM_SYS_TIMCTL_BASE PLAT_ARM_SYS_TIMCTL_BASE +#else #define ARM_SYS_TIMCTL_BASE UL(0x2a810000) +#endif + +#ifdef PLAT_ARM_SYS_CNT_BASE_S +#define ARM_SYS_CNT_BASE_S PLAT_ARM_SYS_CNT_BASE_S +#else #define ARM_SYS_CNT_BASE_S UL(0x2a820000) +#endif + +#ifdef PLAT_ARM_SYS_CNT_BASE_NS +#define ARM_SYS_CNT_BASE_NS PLAT_ARM_SYS_CNT_BASE_NS +#else #define ARM_SYS_CNT_BASE_NS UL(0x2a830000) +#endif #define ARM_CONSOLE_BAUDRATE 115200 /* Trusted Watchdog constants */ +#ifdef PLAT_ARM_SP805_TWDG_BASE +#define ARM_SP805_TWDG_BASE PLAT_ARM_SP805_TWDG_BASE +#else #define ARM_SP805_TWDG_BASE UL(0x2a490000) +#endif #define ARM_SP805_TWDG_CLK_HZ 32768 /* The TBBR document specifies a watchdog timeout of 256 seconds. SP805 * asserts reset after two consecutive countdowns (2 x 128 = 256 sec) */ diff --git a/lib/xlat_mpu/aarch64/enable_mpu.S b/lib/xlat_mpu/aarch64/enable_mpu.S new file mode 100644 index 000000000..3791f2d9d --- /dev/null +++ b/lib/xlat_mpu/aarch64/enable_mpu.S @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + .global enable_mpu_direct_el2 + + /* void enable_mmu_direct_el2(unsigned int flags) */ +func enable_mpu_direct_el2 +#if ENABLE_ASSERTIONS + mrs x1, sctlr_el2 + tst x1, #SCTLR_M_BIT + ASM_ASSERT(eq) +#endif + mov x7, x0 + adrp x0, mmu_cfg_params + add x0, x0, :lo12:mmu_cfg_params + + /* (MAIRs are already set up) */ + + /* TCR */ + ldr x2, [x0, #(MMU_CFG_TCR << 3)] + msr tcr_el2, x2 + + /* + * Ensure all translation table writes have drained into memory, the TLB + * invalidation is complete, and translation register writes are + * committed before enabling the MMU + */ + dsb ish + isb + + /* Set and clear required fields of SCTLR */ + mrs x4, sctlr_el2 + mov_imm x5, SCTLR_WXN_BIT | SCTLR_C_BIT | SCTLR_M_BIT + orr x4, x4, x5 + + /* Additionally, amend SCTLR fields based on flags */ + bic x5, x4, #SCTLR_C_BIT + tst x7, #DISABLE_DCACHE + csel x4, x5, x4, ne + + msr sctlr_el2, x4 + isb + + ret +endfunc enable_mpu_direct_el2 diff --git a/lib/xlat_mpu/aarch64/xlat_mpu_arch.c b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c new file mode 100644 index 000000000..5068eb8d4 --- /dev/null +++ b/lib/xlat_mpu/aarch64/xlat_mpu_arch.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include "../xlat_mpu_private.h" +#include +#include +#include +#include +#include + +#include + +#warning "xlat_mpu library is currently experimental and its API may change in future." + +#if ENABLE_ASSERTIONS +/* + * Return minimum virtual address space size supported by the architecture + */ +uintptr_t xlat_get_min_virt_addr_space_size(void) +{ + uintptr_t ret; + + if (is_armv8_4_ttst_present()) { + ret = MIN_VIRT_ADDR_SPACE_SIZE_TTST; + } else { + ret = MIN_VIRT_ADDR_SPACE_SIZE; + } + return ret; +} +#endif /* ENABLE_ASSERTIONS*/ + +bool is_mpu_enabled_ctx(const xlat_ctx_t *ctx) +{ + if (ctx->xlat_regime == EL1_EL0_REGIME) { + assert(xlat_arch_current_el() >= 1U); + return (read_sctlr_el1() & SCTLR_M_BIT) != 0U; + } else { + assert(xlat_arch_current_el() >= 2U); + return (read_sctlr_el2() & SCTLR_M_BIT) != 0U; + } +} + +bool is_dcache_enabled(void) +{ + unsigned int el = get_current_el(); + + if (el == 1U) { + return (read_sctlr_el1() & SCTLR_C_BIT) != 0U; + } else { /* must be EL2 */ + return (read_sctlr_el2() & SCTLR_C_BIT) != 0U; + } +} + +unsigned int xlat_arch_current_el(void) +{ + unsigned int el = (unsigned int)GET_EL(read_CurrentEl()); + + assert(el > 0U); + + return el; +} + diff --git a/lib/xlat_mpu/ro_xlat_mpu.mk b/lib/xlat_mpu/ro_xlat_mpu.mk new file mode 100644 index 000000000..23f1d46b2 --- /dev/null +++ b/lib/xlat_mpu/ro_xlat_mpu.mk @@ -0,0 +1,14 @@ +# +# Copyright (c) 2021, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifeq (${USE_DEBUGFS}, 1) + $(error "Debugfs requires functionality from the dynamic translation \ + library and is incompatible with ALLOW_RO_XLAT_TABLES.") +endif + +ifeq (${ARCH},aarch32) + $(error "The xlat_mpu library does not currently support AArch32.") +endif diff --git a/lib/xlat_mpu/xlat_mpu.h b/lib/xlat_mpu/xlat_mpu.h new file mode 100644 index 000000000..f46805a42 --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef XLAT_MPU_H +#define XLAT_MPU_H + +#define XLAT_TABLES_LIB_V2 1 + +void enable_mpu_el2(unsigned int flags); +void enable_mpu_direct_el2(unsigned int flags); + +/* + * Function to wipe clean and disable all MPU regions. This function expects + * that the MPU has already been turned off, and caching concerns addressed, + * but it nevertheless also explicitly turns off the MPU. + */ +void clear_all_mpu_regions(void); + +#endif /* XLAT_MPU_H */ diff --git a/lib/xlat_mpu/xlat_mpu.mk b/lib/xlat_mpu/xlat_mpu.mk new file mode 100644 index 000000000..041b91c86 --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu.mk @@ -0,0 +1,19 @@ +# +# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +XLAT_MPU_LIB_V1_SRCS := $(addprefix lib/xlat_mpu/, \ + ${ARCH}/enable_mpu.S \ + ${ARCH}/xlat_mpu_arch.c \ + xlat_mpu_context.c \ + xlat_mpu_core.c \ + xlat_mpu_utils.c) + +XLAT_MPU_LIB_V1 := 1 +$(eval $(call add_define,XLAT_MPU_LIB_V1)) + +ifeq (${ALLOW_XLAT_MPU}, 1) + include lib/xlat_mpu_v2/ro_xlat_mpu.mk +endif diff --git a/lib/xlat_mpu/xlat_mpu_context.c b/lib/xlat_mpu/xlat_mpu_context.c new file mode 100644 index 000000000..7cb19dbcc --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu_context.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include "xlat_mpu.h" +#include "xlat_mpu_private.h" + +#include +#include + +#warning "xlat_mpu library is currently experimental and its API may change in future." + + +/* + * MMU configuration register values for the active translation context. Used + * from the MMU assembly helpers. + */ +uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; + +/* + * Allocate and initialise the default translation context for the BL image + * currently executing. + */ +REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES, + PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE); + +void mmap_add(const mmap_region_t *mm) +{ + mmap_add_ctx(&tf_xlat_ctx, mm); +} + +void __init init_xlat_tables(void) +{ + assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID); + + unsigned int current_el = xlat_arch_current_el(); + + if (current_el == 1U) { + tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME; + } else { + assert(current_el == 2U); + tf_xlat_ctx.xlat_regime = EL2_REGIME; + } + /* Note: If EL3 is supported in future v8-R64, add EL3 assignment */ + init_xlat_tables_ctx(&tf_xlat_ctx); +} + +int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr) +{ + return xlat_get_mem_attributes_ctx(&tf_xlat_ctx, base_va, attr); +} + +void enable_mpu_el2(unsigned int flags) +{ + /* EL2 is strictly MPU on v8-R64, so no need for setup_mpu_cfg() */ + enable_mpu_direct_el2(flags); +} diff --git a/lib/xlat_mpu/xlat_mpu_core.c b/lib/xlat_mpu/xlat_mpu_core.c new file mode 100644 index 000000000..6b4b0c2ef --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu_core.c @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "xlat_mpu_private.h" + +#include +#include + +#warning "xlat_mpu library is currently experimental and its API may change in future." + + +/* Helper function that cleans the data cache only if it is enabled. */ +static inline __attribute__((unused)) + void xlat_clean_dcache_range(uintptr_t addr, size_t size) +{ + if (is_dcache_enabled()) { + clean_dcache_range(addr, size); + } +} + + + +/* Calculate region-attributes byte for PRBAR part of MPU-region descriptor: */ +uint64_t prbar_attr_value(uint32_t attr) +{ + uint64_t retValue = UL(0); + uint64_t extract; /* temp var holding bit extracted from attr */ + + /* Extract and stuff SH: */ + extract = (uint64_t) ((attr >> MT_SHAREABILITY_SHIFT) + & MT_SHAREABILITY_MASK); + retValue |= (extract << PRBAR_SH_SHIFT); + + /* Extract and stuff AP: */ + extract = (uint64_t) ((attr >> MT_PERM_SHIFT) & MT_PERM_MASK); + if (extract == 0U) { + retValue |= (UL(2) << PRBAR_AP_SHIFT); + } else /* extract == 1 */ { + retValue |= (UL(0) << PRBAR_AP_SHIFT); + } + + /* Extract and stuff XN: */ + extract = (uint64_t) ((attr >> MT_EXECUTE_SHIFT) & MT_EXECUTE_MASK); + retValue |= (extract << PRBAR_XN_SHIFT); + /* However, also don't execute in peripheral space: */ + extract = (uint64_t) ((attr >> MT_TYPE_SHIFT) & MT_TYPE_MASK); + if (extract == 0U) { + retValue |= (UL(1) << PRBAR_XN_SHIFT); + } + return retValue; +} + +/* Calculate region-attributes byte for PRLAR part of MPU-region descriptor: */ +uint64_t prlar_attr_value(uint32_t attr) +{ + uint64_t retValue = UL(0); + uint64_t extract; /* temp var holding bit extracted from attr */ + + /* Extract and stuff AttrIndx: */ + extract = (uint64_t) ((attr >> MT_TYPE_SHIFT) + & MT_TYPE_MASK); + switch (extract) { + case UL(0): + retValue |= (UL(1) << PRLAR_ATTR_SHIFT); + break; + case UL(2): + /* 0, so OR in nothing */ + break; + case UL(3): + retValue |= (UL(2) << PRLAR_ATTR_SHIFT); + break; + default: + retValue |= (extract << PRLAR_ATTR_SHIFT); + break; + } + + /* Stuff EN: */ + retValue |= (UL(1) << PRLAR_EN_SHIFT); + + /* Force NS to 0 (Secure); v8-R64 only supports Secure: */ + extract = ~(1U << PRLAR_NS_SHIFT); + retValue &= extract; + + return retValue; +} + +/* + * Function that writes an MPU "translation" into the MPU registers. If not + * possible (e.g., if no more MPU regions available) boot is aborted. + */ +static void mpu_map_region(mmap_region_t *mm) +{ + uint64_t prenr_el2_value = 0UL; + uint64_t prbar_attrs = 0UL; + uint64_t prlar_attrs = 0UL; + int region_to_use = 0; + + /* If all MPU regions in use, then abort boot: */ + prenr_el2_value = read_prenr_el2(); + assert(prenr_el2_value != 0xffffffff); + + /* Find and select first-available MPU region (PRENR has an enable bit + * for each MPU region, 1 for in-use or 0 for unused): + */ + for (region_to_use = 0; region_to_use < N_MPU_REGIONS; + region_to_use++) { + if (((prenr_el2_value >> region_to_use) & 1) == 0) { + break; + } + } + write_prselr_el2((uint64_t) (region_to_use)); + isb(); + + /* Set base and limit addresses: */ + write_prbar_el2(mm->base_pa & PRBAR_PRLAR_ADDR_MASK); + write_prlar_el2((mm->base_pa + mm->size - 1UL) + & PRBAR_PRLAR_ADDR_MASK); + dsbsy(); + isb(); + + /* Set attributes: */ + prbar_attrs = prbar_attr_value(mm->attr); + write_prbar_el2(read_prbar_el2() | prbar_attrs); + prlar_attrs = prlar_attr_value(mm->attr); + write_prlar_el2(read_prlar_el2() | prlar_attrs); + dsbsy(); + isb(); + + /* Mark this MPU region as used: */ + prenr_el2_value |= (1 << region_to_use); + write_prenr_el2(prenr_el2_value); + isb(); +} + +/* + * Function that verifies that a region can be mapped. + * Returns: + * 0: Success, the mapping is allowed. + * EINVAL: Invalid values were used as arguments. + * ERANGE: The memory limits were surpassed. + * ENOMEM: There is not enough memory in the mmap array. + * EPERM: Region overlaps another one in an invalid way. + */ +static int mmap_add_region_check(const xlat_ctx_t *ctx, const mmap_region_t *mm) +{ + unsigned long long base_pa = mm->base_pa; + uintptr_t base_va = mm->base_va; + size_t size = mm->size; + + unsigned long long end_pa = base_pa + size - 1U; + uintptr_t end_va = base_va + size - 1U; + + if (base_pa != base_va) { + return -EINVAL; /* MPU does not perform address translation */ + } + if ((base_pa % 64ULL) != 0ULL) { + return -EINVAL; /* MPU requires 64-byte alignment */ + } + /* Check for overflows */ + if ((base_pa > end_pa) || (base_va > end_va)) { + return -ERANGE; + } + if (end_pa > ctx->pa_max_address) { + return -ERANGE; + } + /* Check that there is space in the ctx->mmap array */ + if (ctx->mmap[ctx->mmap_num - 1].size != 0U) { + return -ENOMEM; + } + /* Check for PAs and VAs overlaps with all other regions */ + for (const mmap_region_t *mm_cursor = ctx->mmap; + mm_cursor->size != 0U; ++mm_cursor) { + + uintptr_t mm_cursor_end_va = + mm_cursor->base_va + mm_cursor->size - 1U; + + /* + * Check if one of the regions is completely inside the other + * one. + */ + bool fully_overlapped_va = + ((base_va >= mm_cursor->base_va) && + (end_va <= mm_cursor_end_va)) || + ((mm_cursor->base_va >= base_va) && + (mm_cursor_end_va <= end_va)); + + /* + * Full VA overlaps are only allowed if both regions are + * identity mapped (zero offset) or have the same VA to PA + * offset. Also, make sure that it's not the exact same area. + * This can only be done with static regions. + */ + if (fully_overlapped_va) { + +#if PLAT_XLAT_TABLES_DYNAMIC + if (((mm->attr & MT_DYNAMIC) != 0U) || + ((mm_cursor->attr & MT_DYNAMIC) != 0U)) { + return -EPERM; + } +#endif /* PLAT_XLAT_TABLES_DYNAMIC */ + if ((mm_cursor->base_va - mm_cursor->base_pa) + != (base_va - base_pa)) { + return -EPERM; + } + if ((base_va == mm_cursor->base_va) && + (size == mm_cursor->size)) { + return -EPERM; + } + } else { + /* + * If the regions do not have fully overlapping VAs, + * then they must have fully separated VAs and PAs. + * Partial overlaps are not allowed + */ + + unsigned long long mm_cursor_end_pa = + mm_cursor->base_pa + mm_cursor->size - 1U; + + bool separated_pa = (end_pa < mm_cursor->base_pa) || + (base_pa > mm_cursor_end_pa); + bool separated_va = (end_va < mm_cursor->base_va) || + (base_va > mm_cursor_end_va); + + if (!separated_va || !separated_pa) { + return -EPERM; + } + } + } + + return 0; +} + +void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) +{ + mmap_region_t *mm_cursor = ctx->mmap, *mm_destination; + const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num; + const mmap_region_t *mm_last; + unsigned long long end_pa = mm->base_pa + mm->size - 1U; + uintptr_t end_va = mm->base_va + mm->size - 1U; + int ret; + + /* Ignore empty regions */ + if (mm->size == 0U) { + return; + } + + /* Static regions must be added before initializing the xlat tables. */ + assert(!ctx->initialized); + + ret = mmap_add_region_check(ctx, mm); + if (ret != 0) { + ERROR("mmap_add_region_check() failed. error %d\n", ret); + assert(false); + return; + } + + /* + * Find the last entry marker in the mmap + */ + mm_last = ctx->mmap; + while ((mm_last->size != 0U) && (mm_last < mm_end)) { + ++mm_last; + } + + /* + * Check if we have enough space in the memory mapping table. + * This shouldn't happen as we have checked in mmap_add_region_check + * that there is free space. + */ + assert(mm_last->size == 0U); + + /* Make room for new region by moving other regions up by one place */ + mm_destination = mm_cursor + 1; + (void)memmove(mm_destination, mm_cursor, + (uintptr_t)mm_last - (uintptr_t)mm_cursor); + + /* + * Check we haven't lost the empty sentinel from the end of the array. + * This shouldn't happen as we have checked in mmap_add_region_check + * that there is free space. + */ + assert(mm_end->size == 0U); + + *mm_cursor = *mm; + + if (end_pa > ctx->max_pa) { + ctx->max_pa = end_pa; + } + if (end_va > ctx->max_va) { + ctx->max_va = end_va; + } +} + +void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm) +{ + const mmap_region_t *mm_cursor = mm; + + while (mm_cursor->granularity != 0U) { + mmap_add_region_ctx(ctx, mm_cursor); + mm_cursor++; + } +} + +void __init init_xlat_tables_ctx(xlat_ctx_t *ctx) +{ + uint64_t mair = UL(0); + + assert(ctx != NULL); + assert(!ctx->initialized); + assert((ctx->xlat_regime == EL2_REGIME) || + (ctx->xlat_regime == EL1_EL0_REGIME)); + /* Note: Add EL3_REGIME if EL3 is supported in future v8-R64 cores. */ + assert(!is_mpu_enabled_ctx(ctx)); + + mmap_region_t *mm = ctx->mmap; + + assert(ctx->va_max_address >= + (xlat_get_min_virt_addr_space_size() - 1U)); + assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U)); + assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U)); + + xlat_mmap_print(mm); + + /* All tables must be zeroed before mapping any region. */ + + for (unsigned int i = 0U; i < ctx->base_table_entries; i++) + ctx->base_table[i] = INVALID_DESC; + + /* Also mark all MPU regions as invalid in the MPU hardware itself: */ + write_prenr_el2(0); + /* Sufficient for current, max-32-region implementations. */ + dsbsy(); + isb(); + while (mm->size != 0U) { + if (read_prenr_el2() == ALL_MPU_EL2_REGIONS_USED) { + ERROR("Not enough MPU regions to map region:\n" + " VA:0x%lx PA:0x%llx size:0x%zx attr:0x%x\n", + mm->base_va, mm->base_pa, mm->size, mm->attr); + panic(); + } else { +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + xlat_clean_dcache_range((uintptr_t)mm->base_va, + mm->size); +#endif + mpu_map_region(mm); + } + mm++; + } + + ctx->initialized = true; + + xlat_tables_print(ctx); + + /* Set attributes in the right indices of the MAIR */ + mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); + mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, + ATTR_IWBWA_OWBWA_NTR_INDEX); + mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, + ATTR_NON_CACHEABLE_INDEX); + write_mair_el2(mair); + dsbsy(); + isb(); +} + +/* + * Function to wipe clean and disable all MPU regions. This function expects + * that the MPU has already been turned off, and caching concerns addressed, + * but it nevertheless also explicitly turns off the MPU. + */ +void clear_all_mpu_regions(void) +{ + uint64_t sctlr_el2_value = 0UL; + uint64_t region_n = 0UL; + + /* + * MPU should already be disabled, but explicitly disable it + * nevertheless: + */ + sctlr_el2_value = read_sctlr_el2() & ~(1UL); + write_sctlr_el2(sctlr_el2_value); + + /* Disable all regions: */ + write_prenr_el2(0UL); + + /* Sequence through all regions, zeroing them out and turning off: */ + for (region_n = 0UL; region_n < N_MPU_REGIONS; region_n++) { + write_prselr_el2(region_n); + isb(); + write_prbar_el2((uint64_t) 0); + write_prlar_el2((uint64_t) 0); + dsbsy(); + isb(); + } +} diff --git a/lib/xlat_mpu/xlat_mpu_private.h b/lib/xlat_mpu/xlat_mpu_private.h new file mode 100644 index 000000000..e0e479d21 --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu_private.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef XLAT_MPU_PRIVATE_H +#define XLAT_MPU_PRIVATE_H + +#include + +#include +#include + +#include + +#if PLAT_XLAT_TABLES_DYNAMIC +/* + * Private shifts and masks to access fields of an mmap attribute + */ +/* Dynamic or static */ +#define MT_DYN_SHIFT U(31) + +/* + * Memory mapping private attributes + * + * Private attributes not exposed in the public header. + */ + +#endif /* PLAT_XLAT_TABLES_DYNAMIC */ + +/* Calculate region-attributes byte for PRBAR part of MPU-region descriptor: */ +uint64_t prbar_attr_value(uint32_t attr); +/* Calculate region-attributes byte for PRLAR part of MPU-region descriptor: */ +uint64_t prlar_attr_value(uint32_t attr); +/* Calculates the attr value for a given PRBAR and PRLAR entry value: */ +uint32_t region_attr(uint64_t prbar_attr, uint64_t prlar_attr); + +#define PRBAR_PRLAR_ADDR_MASK UL(0xffffffffffc0) + /* mask for PRBAR & PRLAR MPU-region field */ +/* MPU region attribute bit fields: */ +#define PRBAR_SH_SHIFT UL(4) +#define PRBAR_SH_MASK UL(0x3) +#define PRBAR_AP_SHIFT UL(2) +#define PRBAR_AP_MASK UL(0x3) +#define PRBAR_XN_SHIFT UL(1) +#define PRBAR_XN_MASK UL(0x3) +#define PRLAR_NS_SHIFT UL(4) +#define PRLAR_NS_MASK UL(0x3) +#define PRBAR_ATTR_SHIFT UL(0) +#define PRBAR_ATTR_MASK UL(0x3f) +#define PRLAR_ATTR_SHIFT UL(1) +#define PRLAR_ATTR_MASK UL(0x7) +#define PRLAR_EN_SHIFT UL(0) +#define PRLAR_EN_MASK UL(0x1) +/* Aspects of the source attributes not defined elsewhere: */ +#define MT_PERM_MASK UL(0x1) +#define MT_SEC_MASK UL(0x1) +#define MT_EXECUTE_MASK UL(0x3) +#define MT_TYPE_SHIFT UL(0) + +extern uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; + +/* + * Return the execute-never mask that will prevent instruction fetch at the + * given translation regime. + */ +uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime); + +/* Print VA, PA, size and attributes of all regions in the mmap array. */ +void xlat_mmap_print(const mmap_region_t *mmap); + +/* + * Print the current state of the translation tables by reading them from + * memory. + */ +void xlat_tables_print(xlat_ctx_t *ctx); + +/* + * Returns a block/page table descriptor for the given level and attributes. + */ +uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, + unsigned long long addr_pa, unsigned int level); + +/* + * Architecture-specific initialization code. + */ + +/* Returns the current Exception Level. The returned EL must be 1 or higher. */ +unsigned int xlat_arch_current_el(void); + +/* + * Returns true if the MMU of the translation regime managed by the given + * xlat_ctx_t is enabled, false otherwise. + */ +bool is_mpu_enabled_ctx(const xlat_ctx_t *ctx); + +/* + * Returns minimum virtual address space size supported by the architecture + */ +uintptr_t xlat_get_min_virt_addr_space_size(void); + +#endif /* XLAT_MPU_PRIVATE_H */ diff --git a/lib/xlat_mpu/xlat_mpu_utils.c b/lib/xlat_mpu/xlat_mpu_utils.c new file mode 100644 index 000000000..f305632dd --- /dev/null +++ b/lib/xlat_mpu/xlat_mpu_utils.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "xlat_mpu_private.h" + +#include +#include + +#warning "xlat_mpu library is currently experimental and its API may change in future." + + +#if LOG_LEVEL < LOG_LEVEL_VERBOSE + +void xlat_mmap_print(__unused const mmap_region_t *mmap) +{ + /* Empty */ +} + +void xlat_tables_print(__unused xlat_ctx_t *ctx) +{ + /* Empty */ +} + +#else /* if LOG_LEVEL >= LOG_LEVEL_VERBOSE */ + +static const char *invalid_descriptors_ommited = + "%s(%d invalid descriptors omitted)\n"; + +void xlat_tables_print(xlat_ctx_t *ctx) +{ + const char *xlat_regime_str; + int used_page_tables; + + if (ctx->xlat_regime == EL1_EL0_REGIME) { + xlat_regime_str = "1&0"; + } else if (ctx->xlat_regime == EL2_REGIME) { + xlat_regime_str = "2"; + } else { + assert(ctx->xlat_regime == EL3_REGIME); + xlat_regime_str = "3"; + /* If no EL3 and EL3 tables generated, then need to know. */ + } + VERBOSE("Translation tables state:\n"); + VERBOSE(" Xlat regime: EL%s\n", xlat_regime_str); + VERBOSE(" Max allowed PA: 0x%llx\n", ctx->pa_max_address); + VERBOSE(" Max allowed VA: 0x%lx\n", ctx->va_max_address); + VERBOSE(" Max mapped PA: 0x%llx\n", ctx->max_pa); + VERBOSE(" Max mapped VA: 0x%lx\n", ctx->max_va); + + VERBOSE(" Initial lookup level: %u\n", ctx->base_level); + VERBOSE(" Entries @initial lookup level: %u\n", + ctx->base_table_entries); + + xlat_tables_print_internal(ctx, 0U, ctx->base_table, + ctx->base_table_entries, ctx->base_level); +} + +#endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */ diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index c86412c9b..dc167e3a6 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -147,7 +147,7 @@ void init_xlat_tables(void) * exception level ******************************************************************************/ #define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct) \ - void enable_mmu_el##_el(unsigned int flags) \ + void enable_mmu_el##_el(unsigned int flags) \ { \ uint64_t mair, tcr, ttbr; \ uint32_t sctlr; \ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c new file mode 100644 index 000000000..ae6af6c08 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "../../../../bl1/bl1_private.h" +#include + +#include + +/******************************************************************************* + * Function that does the first bit of architectural setup that affects + * execution in the non-secure address space. + ******************************************************************************/ +void bl1_arch_setup(void) +{ + /* v8-R64 does not include SCRs. */ +} + +/******************************************************************************* + * Set the Secure EL1 required architectural state + ******************************************************************************/ +void bl1_arch_next_el_setup(void) +{ + u_register_t next_sctlr; + + /* Use the same endianness than the current BL */ + next_sctlr = (read_sctlr_el2() & SCTLR_EE_BIT); + + /* Set SCTLR Secure EL1 */ + next_sctlr |= SCTLR_EL1_RES1; + + write_sctlr_el1(next_sctlr); +} diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c new file mode 100644 index 000000000..1a1851766 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "../../../../bl1/bl1_private.h" +#include +#include +#include +#include + +#include + + +void cm_prepare_el2_exit(uint32_t security_state); + +/* Following contains the cpu context pointers. */ +static void *bl1_cpu_context_ptr[2]; + +void *cm_get_context(uint32_t security_state) +{ + assert(sec_state_is_valid(security_state)); + return bl1_cpu_context_ptr[security_state]; +} + +void cm_set_context(void *context, uint32_t security_state) +{ + assert(sec_state_is_valid(security_state)); + bl1_cpu_context_ptr[security_state] = context; +} + +/******************************************************************************* + * This function prepares the context for Secure/Normal world images. + * Normal world images are transitioned to EL2(if supported) else EL1. + ******************************************************************************/ +void bl1_prepare_next_image(unsigned int image_id) +{ + /* + * Following array will be used for context management. + * There are 2 instances, for the Secure and Non-Secure contexts. + */ + static cpu_context_t bl1_cpu_context[2]; + + unsigned int security_state, mode = MODE_EL1; + image_desc_t *desc; + entry_point_info_t *next_bl_ep; + +#if CTX_INCLUDE_AARCH32_REGS + /* + * Ensure that the build flag to save AArch32 system registers in CPU + * context is not set for AArch64-only platforms. + */ + if (el_implemented(1) == EL_IMPL_A64ONLY) { + ERROR("EL1 supports AArch64-only. Please set build flag %s", + "CTX_INCLUDE_AARCH32_REGS = 0\n"); + panic(); + } +#endif + + /* Get the image descriptor. */ + desc = bl1_plat_get_image_desc(image_id); + assert(desc != NULL); + + /* Get the entry point info. */ + next_bl_ep = &desc->ep_info; + + /* Get the image security state. */ + security_state = GET_SECURITY_STATE(next_bl_ep->h.attr); + + /* Setup the Secure/Non-Secure context if not done already. */ + if (cm_get_context(security_state) == NULL) { + cm_set_context(&bl1_cpu_context[security_state], security_state); + } + /* Prepare the SPSR for the next BL image. */ + if ((security_state != SECURE) && (el_implemented(2) != EL_IMPL_NONE)) { + mode = MODE_EL2; + } + + next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode, + (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + + /* Allow platform to make change */ + bl1_plat_set_ep_info(image_id, next_bl_ep); + + /* Prepare the context for the next BL image. */ + cm_init_my_context(next_bl_ep); + cm_prepare_el2_exit(security_state); + + /* Indicate that image is in execution state. */ + desc->state = IMAGE_STATE_EXECUTED; + + print_entry_point_info(next_bl_ep); +} diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S new file mode 100644 index 000000000..d2e8ac8bf --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + + .globl bl1_entrypoint + + + /* ----------------------------------------------------- + * bl1_entrypoint() is the entry point into the trusted + * firmware code when a cpu is released from warm or + * cold reset. + * ----------------------------------------------------- + */ + +func bl1_entrypoint + /* --------------------------------------------------------------------- + * If the reset address is programmable then bl1_entrypoint() is + * executed only on the cold boot path. Therefore, we can skip the warm + * boot mailbox mechanism. + * --------------------------------------------------------------------- + */ + el2_entrypoint_common \ + _init_sctlr=1 \ + _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ + _init_memory=1 \ + _init_c_runtime=1 \ + _exception_vectors=bl1_exceptions \ + _pie_fixup_size=0 + + /* -------------------------------------------------------------------- + * Perform BL1 setup + * -------------------------------------------------------------------- + */ + bl bl1_setup + +#if ENABLE_PAUTH + /* -------------------------------------------------------------------- + * Program APIAKey_EL1 and enable pointer authentication. + * -------------------------------------------------------------------- + */ + bl pauth_init_enable_el2 +#endif /* ENABLE_PAUTH */ + + /* -------------------------------------------------------------------- + * Initialize platform and jump to our c-entry point + * for this type of reset. + * -------------------------------------------------------------------- + */ + bl bl1_main + +#if ENABLE_PAUTH + /* -------------------------------------------------------------------- + * Disable pointer authentication before jumping to next boot image. + * -------------------------------------------------------------------- + */ + bl pauth_disable_el2 +#endif /* ENABLE_PAUTH */ + + /* -------------------------------------------------- + * Do the transition to next boot image. + * -------------------------------------------------- + */ + b el2_exit +endfunc bl1_entrypoint diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S b/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S new file mode 100644 index 000000000..43c2e01a2 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/* ----------------------------------------------------------------------------- + * File contains an EL2 equivalent of the EL3 vector table from: + * .../bl1/aarch64/bl1_exceptions.S + * ----------------------------------------------------------------------------- + */ + +/* ----------------------------------------------------------------------------- + * Very simple stackless exception handlers used by BL1. + * ----------------------------------------------------------------------------- + */ + .globl bl1_exceptions + +vector_base bl1_exceptions + + /* ----------------------------------------------------- + * Current EL with SP0 : 0x0 - 0x200 + * ----------------------------------------------------- + */ +vector_entry SynchronousExceptionSP0 + mov x0, #SYNC_EXCEPTION_SP_EL0 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry SynchronousExceptionSP0 + +vector_entry IrqSP0 + mov x0, #IRQ_SP_EL0 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry IrqSP0 + +vector_entry FiqSP0 + mov x0, #FIQ_SP_EL0 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry FiqSP0 + +vector_entry SErrorSP0 + mov x0, #SERROR_SP_EL0 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry SErrorSP0 + + /* ----------------------------------------------------- + * Current EL with SPx: 0x200 - 0x400 + * ----------------------------------------------------- + */ +vector_entry SynchronousExceptionSPx + mov x0, #SYNC_EXCEPTION_SP_ELX + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry SynchronousExceptionSPx + +vector_entry IrqSPx + mov x0, #IRQ_SP_ELX + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry IrqSPx + +vector_entry FiqSPx + mov x0, #FIQ_SP_ELX + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry FiqSPx + +vector_entry SErrorSPx + mov x0, #SERROR_SP_ELX + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry SErrorSPx + + /* ----------------------------------------------------- + * Lower EL using AArch64 : 0x400 - 0x600 + * ----------------------------------------------------- + */ +vector_entry SynchronousExceptionA64 + /* The current v8-R64 implementation does not support conduit calls */ + b el2_panic +end_vector_entry SynchronousExceptionA64 + +vector_entry IrqA64 + mov x0, #IRQ_AARCH64 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry IrqA64 + +vector_entry FiqA64 + mov x0, #FIQ_AARCH64 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry FiqA64 + +vector_entry SErrorA64 + mov x0, #SERROR_AARCH64 + bl plat_report_exception + no_ret plat_panic_handler +end_vector_entry SErrorA64 + + +unexpected_sync_exception: + mov x0, #SYNC_EXCEPTION_AARCH64 + bl plat_report_exception + no_ret plat_panic_handler + + /* ----------------------------------------------------- + * Save Secure/Normal world context and jump to + * BL1 SMC handler. + * ----------------------------------------------------- + */ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c new file mode 100644 index 000000000..b13ce9f0e --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "../../../../bl1/bl1_private.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +static void bl1_load_bl2(void); + +#if ENABLE_PAUTH +uint64_t bl1_apiakey[2]; +#endif + +/******************************************************************************* + * Helper utility to calculate the BL2 memory layout taking into consideration + * the BL1 RW data assuming that it is at the top of the memory layout. + ******************************************************************************/ +void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, + meminfo_t *bl2_mem_layout) +{ + assert(bl1_mem_layout != NULL); + assert(bl2_mem_layout != NULL); + + /* + * Remove BL1 RW data from the scope of memory visible to BL2. + * This is assuming BL1 RW data is at the top of bl1_mem_layout. + */ + assert(bl1_mem_layout->total_base < BL1_RW_BASE); + bl2_mem_layout->total_base = bl1_mem_layout->total_base; + bl2_mem_layout->total_size = BL1_RW_BASE - bl1_mem_layout->total_base; + + flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); +} + +/******************************************************************************* + * Setup function for BL1. + ******************************************************************************/ +void bl1_setup(void) +{ + /* Perform early platform-specific setup */ + bl1_early_platform_setup(); + + /* Perform late platform-specific setup */ + bl1_plat_arch_setup(); + +#if CTX_INCLUDE_PAUTH_REGS + /* + * Assert that the ARMv8.3-PAuth registers are present or an access + * fault will be triggered when they are being saved or restored. + */ + assert(is_armv8_3_pauth_present()); +#endif /* CTX_INCLUDE_PAUTH_REGS */ +} + +/******************************************************************************* + * Function to perform late architectural and platform specific initialization. + * It also queries the platform to load and run next BL image. Only called + * by the primary cpu after a cold boot. + ******************************************************************************/ +void bl1_main(void) +{ + unsigned int image_id; + + /* Announce our arrival */ + NOTICE(FIRMWARE_WELCOME_STR); + NOTICE("BL1: %s\n", version_string); + NOTICE("BL1: %s\n", build_message); + + INFO("BL1: RAM %p - %p\n", (void *)BL1_RAM_BASE, (void *)BL1_RAM_LIMIT); + + print_errata_status(); + +#if ENABLE_ASSERTIONS + u_register_t val; + /* + * Ensure that MMU/Caches and coherency are turned on + */ + val = read_sctlr_el2(); + + assert((val & SCTLR_M_BIT) != 0U); + assert((val & SCTLR_C_BIT) != 0U); + assert((val & SCTLR_I_BIT) != 0U); + /* + * Check that Cache Writeback Granule (CWG) in CTR_EL0 matches the + * provided platform value + */ + val = (read_ctr_el0() >> CTR_CWG_SHIFT) & CTR_CWG_MASK; + /* + * If CWG is zero, then no CWG information is available but we can + * at least check the platform value is less than the architectural + * maximum. + */ + if (val != 0) { + assert(SIZE_FROM_LOG2_WORDS(val) == CACHE_WRITEBACK_GRANULE); + } else { + assert(CACHE_WRITEBACK_GRANULE <= MAX_CACHE_LINE_SIZE); + } +#endif /* ENABLE_ASSERTIONS */ + + /* Perform remaining generic architectural setup from EL2 */ + bl1_arch_setup(); + +#if TRUSTED_BOARD_BOOT + /* Initialize authentication module */ + auth_mod_init(); +#endif /* TRUSTED_BOARD_BOOT */ + + /* Perform platform setup in BL1. */ + bl1_platform_setup(); + +#if ENABLE_PAUTH + /* Store APIAKey_EL1 key */ + bl1_apiakey[0] = read_apiakeylo_el1(); + bl1_apiakey[1] = read_apiakeyhi_el1(); +#endif /* ENABLE_PAUTH */ + + /* Get the image id of next image to load and run. */ + image_id = bl1_plat_get_next_image_id(); + + /* + * We currently interpret any image id other than + * BL2_IMAGE_ID as the start of firmware update. + */ + if (image_id == BL2_IMAGE_ID) { + bl1_load_bl2(); + } else { + NOTICE("BL1-FWU: *******FWU Process Started*******\n"); + } + bl1_prepare_next_image(image_id); + + console_flush(); +} + +/******************************************************************************* + * This function locates and loads the BL2 raw binary image in the trusted SRAM. + * Called by the primary cpu after a cold boot. + * TODO: Add support for alternative image load mechanism e.g using virtio/elf + * loader etc. + ******************************************************************************/ +static void bl1_load_bl2(void) +{ + image_desc_t *desc; + image_info_t *info; + int err; + + /* Get the image descriptor */ + desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(desc != NULL); + + /* Get the image info */ + info = &desc->image_info; + INFO("BL1: Loading BL2\n"); + + err = bl1_plat_handle_pre_image_load(BL2_IMAGE_ID); + if (err != 0) { + ERROR("Failure in pre image load handling of BL2 (%d)\n", err); + plat_error_handler(err); + } + + err = load_auth_image(BL2_IMAGE_ID, info); + if (err != 0) { + ERROR("Failed to load BL2 firmware.\n"); + plat_error_handler(err); + } + + /* Allow platform to handle image information. */ + err = bl1_plat_handle_post_image_load(BL2_IMAGE_ID); + if (err != 0) { + ERROR("Failure in post image load handling of BL2 (%d)\n", err); + plat_error_handler(err); + } + + NOTICE("BL1: Booting BL2\n"); +} + +/******************************************************************************* + * Function called just before handing over to the next BL to inform the user + * about the boot progress. In debug mode, also print details about the BL + * image's execution context. + ******************************************************************************/ +void bl1_print_next_bl_ep_info(const entry_point_info_t *bl_ep_info) +{ + NOTICE("BL1: Booting BL31\n"); + print_entry_point_info(bl_ep_info); +} + +#if SPIN_ON_BL1_EXIT +void print_debug_loop_message(void) +{ + NOTICE("BL1: Debug loop, spinning forever\n"); + NOTICE("BL1: Please connect the debugger to continue\n"); +} +#endif + diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c index 91709d84b..c6fb25ff1 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -4,8 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* Use the xlat_tables_v2 data structures: */ +#define XLAT_TABLES_LIB_V2 1 + #include +#include "../../../../lib/xlat_mpu/xlat_mpu.h" #include #include #include @@ -16,6 +20,56 @@ #include #include +#include + +#define MAP_BL1_TOTAL MAP_REGION_FLAT( \ + bl1_tzram_layout.total_base, \ + bl1_tzram_layout.total_size, \ + MT_MEMORY | MT_RW | MT_SECURE) +/* + * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section + * otherwise one region is defined containing both + */ +#if SEPARATE_CODE_AND_RODATA +#define MAP_BL1_RO MAP_REGION_FLAT( \ + BL_CODE_BASE, \ + BL1_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE), \ + MAP_REGION_FLAT( \ + BL1_RO_DATA_BASE, \ + BL1_RO_DATA_END \ + - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) +#else +#define MAP_BL1_RO MAP_REGION_FLAT( \ + BL_CODE_BASE, \ + BL1_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) +#endif + +/* Data structure which holds the extents of the trusted SRAM for BL1*/ +static meminfo_t bl1_tzram_layout; + +struct meminfo *bl1_plat_sec_mem_layout(void) +{ + return &bl1_tzram_layout; +} + +void arm_bl1_early_platform_setup(void) +{ + +#if !ARM_DISABLE_TRUSTED_WDOG + /* Enable watchdog */ + plat_arm_secure_wdt_start(); +#endif + + /* Initialize the console to provide early debug support */ + arm_console_boot_init(); + + /* Allow BL1 to see the whole Trusted RAM */ + bl1_tzram_layout.total_base = ARM_BL_RAM_BASE; + bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE; +} /******************************************************************************* * Perform any BL1 specific platform actions. @@ -38,6 +92,34 @@ void bl1_early_platform_setup(void) fvp_interconnect_enable(); } +void arm_bl1_plat_arch_setup(void) +{ + const mmap_region_t bl_regions[] = { + MAP_BL1_TOTAL, + MAP_BL1_RO, +#if USE_ROMLIB + ARM_MAP_ROMLIB_CODE, + ARM_MAP_ROMLIB_DATA, +#endif +#if ARM_CRYPTOCELL_INTEG + ARM_MAP_BL_COHERENT_RAM, +#endif + /* DRAM1_region: */ + MAP_REGION_FLAT( \ + PLAT_ARM_DRAM1_BASE, \ + PLAT_ARM_DRAM1_SIZE, \ + MT_MEMORY | MT_SECURE | MT_EXECUTE \ + | MT_RW | MT_NON_CACHEABLE), + /* NULL terminator: */ + {0} + }; + + setup_page_tables(bl_regions, plat_arm_get_mmap()); + enable_mpu_el2(0); + + arm_setup_romlib(); +} + void plat_arm_secure_wdt_start(void) { sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); diff --git a/plat/arm/board/fvp_r/fvp_r_common.c b/plat/arm/board/fvp_r/fvp_r_common.c index 693a6d795..a9316a1a1 100644 --- a/plat/arm/board/fvp_r/fvp_r_common.c +++ b/plat/arm/board/fvp_r/fvp_r_common.c @@ -4,9 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include +/* This uses xlat_mpu, but tables are set up using V2 mmap_region_t */ +#define XLAT_TABLES_LIB_V2 1 +#include #include + #include #include #include @@ -109,7 +112,80 @@ static unsigned int get_interconnect_master(void) ******************************************************************************/ void __init fvp_config_setup(void) { + unsigned int rev, hbi, bld, arch, sys_id; + arm_config.flags |= ARM_CONFIG_BASE_MMAP; + sys_id = mmio_read_32(V2M_FVP_R_SYSREGS_BASE + V2M_SYS_ID); + rev = (sys_id >> V2M_SYS_ID_REV_SHIFT) & V2M_SYS_ID_REV_MASK; + hbi = (sys_id >> V2M_SYS_ID_HBI_SHIFT) & V2M_SYS_ID_HBI_MASK; + bld = (sys_id >> V2M_SYS_ID_BLD_SHIFT) & V2M_SYS_ID_BLD_MASK; + arch = (sys_id >> V2M_SYS_ID_ARCH_SHIFT) & V2M_SYS_ID_ARCH_MASK; + + if (arch != ARCH_MODEL) { + ERROR("This firmware is for FVP_R models\n"); + panic(); + } + + /* + * The build field in the SYS_ID tells which variant of the GIC + * memory is implemented by the model. + */ + switch (bld) { + case BLD_GIC_VE_MMAP: + ERROR("Legacy Versatile Express memory map for GIC %s", + "peripheral is not supported\n"); + panic(); + break; + case BLD_GIC_A53A57_MMAP: + break; + default: + ERROR("Unsupported board build %x\n", bld); + panic(); + } + + /* + * The hbi field in the SYS_ID is 0x020 for the Base FVP_R & 0x010 + * for the Foundation FVP_R. + */ + switch (hbi) { + case HBI_FOUNDATION_FVP_R: + arm_config.flags = 0; + + /* + * Check for supported revisions of Foundation FVP_R + * Allow future revisions to run but emit warning diagnostic + */ + switch (rev) { + case REV_FOUNDATION_FVP_R_V2_0: + case REV_FOUNDATION_FVP_R_V2_1: + case REV_FOUNDATION_FVP_R_v9_1: + case REV_FOUNDATION_FVP_R_v9_6: + break; + default: + WARN("Unrecognized Foundation FVP_R revision %x\n", rev); + break; + } + break; + case HBI_BASE_FVP_R: + arm_config.flags |= (ARM_CONFIG_BASE_MMAP | ARM_CONFIG_HAS_TZC); + + /* + * Check for supported revisions + * Allow future revisions to run but emit warning diagnostic + */ + switch (rev) { + case REV_BASE_FVP_R_V0: + arm_config.flags |= ARM_CONFIG_FVP_HAS_CCI400; + break; + default: + WARN("Unrecognized Base FVP_R revision %x\n", rev); + break; + } + break; + default: + ERROR("Unsupported board HBI number 0x%x\n", hbi); + panic(); + } /* * We assume that the presence of MT bit, and therefore shifted diff --git a/plat/arm/board/fvp_r/fvp_r_context.S b/plat/arm/board/fvp_r/fvp_r_context.S new file mode 100644 index 000000000..2746c2e5b --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_context.S @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .global el2_exit + +/* ------------------------------------------------------------------ + * The mechanism, from el3_exit, is not used in this v8-R64 implementation. + * ------------------------------------------------------------------ + */ +func el2_exit + exception_return +endfunc el2_exit diff --git a/plat/arm/board/fvp_r/fvp_r_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c new file mode 100644 index 000000000..678b8792c --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + + +/******************************************************************************* + * File contains EL2 equivalents of EL3 functions from + * .../lib/el3_runtime/aarch64/context_mgmt.c + ******************************************************************************/ + +/******************************************************************************* + * Prepare the CPU system registers for first entry into secure or normal world + * + * The majority of the work needed is only for switching to non-secure, which + * is not available on v8-R64 cores, so this function is very simple. + ******************************************************************************/ +void cm_prepare_el2_exit(uint32_t security_state) +{ + cm_el1_sysregs_context_restore(security_state); + cm_set_next_eret_context(security_state); +} diff --git a/plat/arm/board/fvp_r/fvp_r_debug.S b/plat/arm/board/fvp_r/fvp_r_debug.S new file mode 100644 index 000000000..8db1b093a --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_debug.S @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl el2_panic + + /*********************************************************** + * The common implementation of do_panic for all BL stages + ***********************************************************/ + +.section .rodata.panic_str, "aS" + panic_msg: .asciz "PANIC at PC : 0x" + +/* + * el2_panic will be redefined by the + * crash reporting mechanism (if enabled) + */ +el2_panic: + mov x6, x30 + bl plat_crash_console_init + + /* Check if the console is initialized */ + cbz x0, _panic_handler + + /* The console is initialized */ + adr x4, panic_msg + bl asm_print_str + mov x4, x6 + + /* The panic location is lr -4 */ + sub x4, x4, #4 + bl asm_print_hex + + bl plat_crash_console_flush + +_panic_handler: + /* Pass to plat_panic_handler the address from where el2_panic was + * called, not the address of the call from el2_panic. */ + mov x30, x6 + b plat_panic_handler diff --git a/plat/arm/board/fvp_r/fvp_r_def.h b/plat/arm/board/fvp_r/fvp_r_def.h index 587832f1c..b9f698939 100644 --- a/plat/arm/board/fvp_r/fvp_r_def.h +++ b/plat/arm/board/fvp_r/fvp_r_def.h @@ -36,40 +36,44 @@ * FVP_R memory map related constants ******************************************************************************/ -#define FLASH1_BASE UL(0x0c000000) +#define FLASH1_BASE UL(0x8c000000) #define FLASH1_SIZE UL(0x04000000) -#define PSRAM_BASE UL(0x14000000) +#define PSRAM_BASE UL(0x94000000) #define PSRAM_SIZE UL(0x04000000) -#define VRAM_BASE UL(0x18000000) +#define VRAM_BASE UL(0x98000000) #define VRAM_SIZE UL(0x02000000) /* Aggregate of all devices in the first GB */ -#define DEVICE0_BASE UL(0x20000000) +#define DEVICE0_BASE UL(0xa0000000) #define DEVICE0_SIZE UL(0x0c200000) /* * In case of FVP_R models with CCN, the CCN register space overlaps into * the NSRAM area. */ -#define DEVICE1_BASE UL(0x2e000000) +#define DEVICE1_BASE UL(0xae000000) #define DEVICE1_SIZE UL(0x1A00000) -#define NSRAM_BASE UL(0x2e000000) + +#define NSRAM_BASE UL(0xae000000) #define NSRAM_SIZE UL(0x10000) /* Devices in the second GB */ -#define DEVICE2_BASE UL(0x7fe00000) +#define DEVICE2_BASE UL(0xffe00000) #define DEVICE2_SIZE UL(0x00200000) +#define PCIE_EXP_BASE UL(0xc0000000) +#define TZRNG_BASE UL(0x7fe60000) + /* Non-volatile counters */ -#define TRUSTED_NVCTR_BASE UL(0x7fe70000) +#define TRUSTED_NVCTR_BASE UL(0xffe70000) #define TFW_NVCTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0000)) #define TFW_NVCTR_SIZE UL(4) #define NTFW_CTR_BASE (TRUSTED_NVCTR_BASE + UL(0x0004)) #define NTFW_CTR_SIZE UL(4) /* Keys */ -#define SOC_KEYS_BASE UL(0x7fe80000) +#define SOC_KEYS_BASE UL(0xffe80000) #define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + UL(0x0000)) #define TZ_PUB_KEY_HASH_SIZE UL(32) #define HU_KEY_BASE (SOC_KEYS_BASE + UL(0x0020)) diff --git a/plat/arm/board/fvp_r/fvp_r_misc_helpers.S b/plat/arm/board/fvp_r/fvp_r_misc_helpers.S new file mode 100644 index 000000000..67ad16400 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_misc_helpers.S @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + + .globl disable_mpu_el2 + .globl disable_mpu_icache_el2 + +/* --------------------------------------------------------------------------- + * Disable the MPU at EL2. + * --------------------------------------------------------------------------- + */ + +func disable_mpu_el2 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT) +do_disable_mpu_el2: + mrs x0, sctlr_el2 + bic x0, x0, x1 + msr sctlr_el2, x0 + isb /* ensure MMU is off */ + dsb sy + ret +endfunc disable_mpu_el2 + + +func disable_mpu_icache_el2 + mov x1, #(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT) + b do_disable_mpu_el2 +endfunc disable_mpu_icache_el2 diff --git a/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S b/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S new file mode 100644 index 000000000..7e6bc3d15 --- /dev/null +++ b/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .global pauth_init_enable_el2 + .global pauth_disable_el2 + +/* ------------------------------------------------------------- + * File contains EL2 versions of EL3 funcs in: + * .../lib/extensions/pauth/pauth_helpers.S + * ------------------------------------------------------------- + */ + +/* ------------------------------------------------------------- + * Program APIAKey_EL1 and enable pointer authentication in EL2 + * ------------------------------------------------------------- + */ +func pauth_init_enable_el2 + stp x29, x30, [sp, #-16]! + + /* Initialize platform key */ + bl plat_init_apkey + + /* Program instruction key A used by the Trusted Firmware */ + msr APIAKeyLo_EL1, x0 + msr APIAKeyHi_EL1, x1 + + /* Enable pointer authentication */ + mrs x0, sctlr_el2 + orr x0, x0, #SCTLR_EnIA_BIT + +#if ENABLE_BTI + /* Enable PAC branch type compatibility */ + bic x0, x0, #SCTLR_BT_BIT +#endif + msr sctlr_el2, x0 + isb + + ldp x29, x30, [sp], #16 + ret +endfunc pauth_init_enable_el2 + +/* ------------------------------------------------------------- + * Disable pointer authentication in EL2 + * ------------------------------------------------------------- + */ +func pauth_disable_el2 + mrs x0, sctlr_el2 + bic x0, x0, #SCTLR_EnIA_BIT + msr sctlr_el2, x0 + isb + ret +endfunc pauth_disable_el2 diff --git a/plat/arm/board/fvp_r/fvp_r_stack_protector.c b/plat/arm/board/fvp_r/fvp_r_stack_protector.c index 5922a9804..69b63122f 100644 --- a/plat/arm/board/fvp_r/fvp_r_stack_protector.c +++ b/plat/arm/board/fvp_r/fvp_r_stack_protector.c @@ -6,7 +6,7 @@ #include -#include +#include #include #define RANDOM_CANARY_VALUE ((u_register_t) 8092347823957523895ULL) diff --git a/plat/arm/board/fvp_r/fvp_r_trusted_boot.c b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c index f304e3e0a..de0b28fe8 100644 --- a/plat/arm/board/fvp_r/fvp_r_trusted_boot.c +++ b/plat/arm/board/fvp_r/fvp_r_trusted_boot.c @@ -22,13 +22,13 @@ * Return the ROTPK hash in the following ASN.1 structure in DER format: * * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters ANY DEFINED BY algorithm OPTIONAL + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL * } * * DigestInfo ::= SEQUENCE { - * digestAlgorithm AlgorithmIdentifier, - * digest OCTET STRING + * digestAlgorithm AlgorithmIdentifier, + * digest OCTET STRING * } */ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, diff --git a/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h b/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h new file mode 100644 index 000000000..92bf48472 --- /dev/null +++ b/plat/arm/board/fvp_r/include/fvp_r_arch_helpers.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_R_ARCH_HELPERS_H +#define FVP_R_ARCH_HELPERS_H + +#include + +/******************************************************************************* + * MPU register definitions + ******************************************************************************/ +#define MPUIR_EL2 S3_4_C0_C0_4 +#define PRBAR_EL2 S3_4_C6_C8_0 +#define PRLAR_EL2 S3_4_C6_C8_1 +#define PRSELR_EL2 S3_4_C6_C2_1 +#define PRENR_EL2 S3_4_C6_C1_1 + +/* v8-R64 MPU registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(mpuir_el2, MPUIR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(prenr_el2, PRENR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(prselr_el2, PRSELR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(prbar_el2, PRBAR_EL2) +DEFINE_RENAME_SYSREG_RW_FUNCS(prlar_el2, PRLAR_EL2) + +#endif /* FVP_R_ARCH_HELPERS_H */ diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h index 458668190..725d13194 100644 --- a/plat/arm/board/fvp_r/include/platform_def.h +++ b/plat/arm/board/fvp_r/include/platform_def.h @@ -4,19 +4,37 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef PLATFORM_DEF_H -#define PLATFORM_DEF_H +#ifndef FVP_R_PLATFORM_DEF_H +#define FVP_R_PLATFORM_DEF_H + +#define PLAT_V2M_OFFSET 0x80000000 #include "../fvp_r_def.h" #include #include #include +/* These are referenced by arm_def.h #included next, so #define first. */ +#define PLAT_ARM_TRUSTED_ROM_BASE UL(0x80000000) +#define PLAT_ARM_TRUSTED_SRAM_BASE UL(0x84000000) +#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x86000000) +#define PLAT_ARM_DRAM1_BASE ULL(0x0) +#define PLAT_ARM_DRAM2_BASE ULL(0x080000000) + +#define PLAT_HW_CONFIG_DTB_BASE ULL(0x12000000) +#define PLAT_ARM_SYS_CNTCTL_BASE UL(0xaa430000) +#define PLAT_ARM_SYS_CNTREAD_BASE UL(0xaa800000) +#define PLAT_ARM_SYS_TIMCTL_BASE UL(0xaa810000) +#define PLAT_ARM_SYS_CNT_BASE_S UL(0xaa820000) +#define PLAT_ARM_SYS_CNT_BASE_NS UL(0xaa830000) +#define PLAT_ARM_SP805_TWDG_BASE UL(0xaa490000) + #include #include -#define NO_EL3 1 +/* Required to create plat_regions: */ +#define MIN_LVL_BLOCK_DESC U(1) /* Required platform porting definitions */ #define PLATFORM_CORE_COUNT (U(FVP_R_CLUSTER_COUNT) * \ @@ -36,34 +54,35 @@ * Required ARM standard platform porting definitions */ #define PLAT_ARM_CLUSTER_COUNT U(FVP_R_CLUSTER_COUNT) - -#define PLAT_ARM_DRAM1_BASE ULL(0x0) - -#define PLAT_ARM_TRUSTED_ROM_BASE UL(0x80000000) -#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x04000000) /* 64 MB */ - -#define PLAT_ARM_TRUSTED_SRAM_BASE UL(0x84000000) +#define PLAT_ARM_DRAM1_SIZE ULL(0x7fffffff) #define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */ - -#define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x86000000) +#define PLAT_ARM_TRUSTED_ROM_SIZE UL(0x04000000) /* 64 MB */ #define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ +/* These two are defined thus in arm_def.h, but doesn't seem to see it... */ +#undef BL1_RO_BASE +#define BL1_RO_BASE PLAT_ARM_TRUSTED_ROM_BASE +#undef BL1_RO_LIMIT +#define BL1_RO_LIMIT (BL1_RO_BASE \ + + PLAT_ARM_TRUSTED_ROM_SIZE) + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) /* No SCP in FVP_R */ #define PLAT_ARM_SCP_TZC_DRAM1_SIZE UL(0x0) -#define PLAT_ARM_DRAM2_BASE ULL(0x080000000) #define PLAT_ARM_DRAM2_SIZE UL(0x80000000) -#define PLAT_HW_CONFIG_DTB_BASE ULL(0x12000000) #define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) #define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ PLAT_HW_CONFIG_DTB_BASE, \ PLAT_HW_CONFIG_DTB_SIZE, \ MT_MEMORY | MT_RO | MT_NS) + +#define V2M_FVP_R_SYSREGS_BASE UL(0x9c010000) + /* * Load address of BL33 for this platform port */ @@ -80,6 +99,9 @@ # define PLAT_ARM_MMAP_ENTRIES 12 # define MAX_XLAT_TABLES 6 #endif +# define N_MPU_REGIONS 16 /* number of MPU regions */ +# define ALL_MPU_EL2_REGIONS_USED 0xffffffff + /* this is the PRENR_EL2 value if all MPU regions are in use */ /* * These nominally reserve the last block of flash for PSCI MEM PROTECT flag, @@ -228,15 +250,10 @@ /* * Physical and virtual address space limits for MPU in AARCH64 & AARCH32 modes */ -#ifdef __aarch64__ #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 36) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 36) -#else -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#endif #define ARM_SOC_CONTINUATION_SHIFT U(24) #define ARM_SOC_IDENTIFICATION_SHIFT U(16) -#endif /* PLATFORM_DEF_H */ +#endif /* FVP_R_PLATFORM_DEF_H */ diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk index 1387ae711..a755432e8 100644 --- a/plat/arm/board/fvp_r/platform.mk +++ b/plat/arm/board/fvp_r/platform.mk @@ -22,6 +22,9 @@ FVP_R_MAX_CPUS_PER_CLUSTER := 4 # Default number of threads per CPU on FVP_R FVP_R_MAX_PE_PER_CPU := 1 +# Use MPU-based memory management: +XLAT_MPU_LIB_V1 := 1 + # Need to revisit this for FVP_R FVP_R_DT_PREFIX := fvp-base-gicv3-psci @@ -76,10 +79,20 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \ drivers/io/io_semihosting.c \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ - plat/arm/board/fvp_r/fvp_r_helpers.S \ + plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \ plat/arm/board/fvp_r/fvp_r_bl1_setup.c \ + plat/arm/board/fvp_r/fvp_r_context_mgmt.c \ plat/arm/board/fvp_r/fvp_r_err.c \ plat/arm/board/fvp_r/fvp_r_io_storage.c \ + plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c \ + plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S \ + plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S \ + plat/arm/board/fvp_r/fvp_r_bl1_main.c \ + plat/arm/board/fvp_r/fvp_r_context.S \ + plat/arm/board/fvp_r/fvp_r_debug.S \ + plat/arm/board/fvp_r/fvp_r_helpers.S \ + plat/arm/board/fvp_r/fvp_r_misc_helpers.S \ + plat/arm/board/fvp_r/fvp_r_pauth_helpers.S \ ${FVP_R_CPU_LIBS} \ ${FVP_R_INTERCONNECT_SOURCES} @@ -96,9 +109,7 @@ ifneq (${ENABLE_STACK_PROTECTOR},0) PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp_r/fvp_r_stack_protector.c endif -ifeq (${ARCH},aarch32) - NEED_BL32 := yes -endif +NEED_BL32 := no ifneq (${BL2_AT_EL3}, 0) override BL1_SOURCES = diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 4b2a062f9..dd8f13bb6 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,9 +22,11 @@ #pragma weak bl1_early_platform_setup #pragma weak bl1_plat_arch_setup #pragma weak bl1_plat_sec_mem_layout +#pragma weak arm_bl1_early_platform_setup #pragma weak bl1_plat_prepare_exit #pragma weak bl1_plat_get_next_image_id #pragma weak plat_arm_bl1_fwu_needed +#pragma weak arm_bl1_plat_arch_setup #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ bl1_tzram_layout.total_base, \ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 58060dbcf..4304db43e 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -206,12 +206,16 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/${ARCH}/arm_helpers.S \ plat/arm/common/arm_console.c ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1) -PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \ +PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/${ARCH}/xlat_tables.c else +ifeq (${XLAT_MPU_LIB_V1}, 1) +include lib/xlat_mpu/xlat_mpu.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_MPU_LIB_V1_SRCS} +else include lib/xlat_tables_v2/xlat_tables.mk - -PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} +endif endif ARM_IO_SOURCES += plat/arm/common/arm_io_storage.c \ @@ -351,7 +355,7 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) - BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ drivers/auth/tbbr/tbbr_cot_bl1.c ifneq (${COT_DESC_IN_DTB},0) BL2_SOURCES += lib/fconf/fconf_cot_getter.c -- cgit v1.2.3 From e31fb0fa1b8a5560d8f7cf2ed2c3b4380106c407 Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Wed, 3 Mar 2021 14:19:38 -0600 Subject: fvp_r: load, auth, and transfer from BL1 to BL33 Adding load, authentication, and transfer functionality from FVP R BL1 to BL33, which will be the partner runtime code. Signed-off-by: Lauren Wehrmeister Change-Id: I293cad09739dacac0d20dd57c1d98178dbe84d40 --- drivers/auth/tbbr/tbbr_cot_bl1_r64.c | 177 ++++++++++++++++++++++++++ include/arch/aarch64/arch_helpers.h | 2 + include/lib/xlat_mpu/xlat_mpu.h | 27 ++++ include/plat/arm/board/fvp_r/fvp_r_bl1.h | 13 ++ include/plat/arm/common/arm_def.h | 17 ++- lib/xlat_mpu/xlat_mpu.h | 22 ---- lib/xlat_mpu/xlat_mpu_context.c | 2 +- make_helpers/tbbr/tbbr_tools.mk | 2 + plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c | 8 -- plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S | 50 +++++++- plat/arm/board/fvp_r/fvp_r_bl1_main.c | 81 +++++++++++- plat/arm/board/fvp_r/fvp_r_bl1_setup.c | 102 ++++++++++++++- plat/arm/board/fvp_r/fvp_r_common.c | 2 - plat/arm/board/fvp_r/fvp_r_err.c | 4 +- plat/arm/board/fvp_r/fvp_r_io_storage.c | 16 +-- plat/arm/board/fvp_r/include/platform_def.h | 45 ++++--- plat/arm/board/fvp_r/platform.mk | 37 ++---- plat/arm/common/arm_bl1_fwu.c | 4 +- plat/arm/common/arm_bl1_setup.c | 1 + plat/arm/common/arm_common.mk | 7 +- 20 files changed, 512 insertions(+), 107 deletions(-) create mode 100644 drivers/auth/tbbr/tbbr_cot_bl1_r64.c create mode 100644 include/lib/xlat_mpu/xlat_mpu.h create mode 100644 include/plat/arm/board/fvp_r/fvp_r_bl1.h delete mode 100644 lib/xlat_mpu/xlat_mpu.h diff --git a/drivers/auth/tbbr/tbbr_cot_bl1_r64.c b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c new file mode 100644 index 000000000..e8e017c8d --- /dev/null +++ b/drivers/auth/tbbr/tbbr_cot_bl1_r64.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include + +#if USE_TBBR_DEFS +#include +#else +#include +#endif +#include + + +static unsigned char trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char non_trusted_world_pk_buf[PK_DER_LEN]; +static unsigned char content_pk_buf[PK_DER_LEN]; +static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN]; + +static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID); +static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID); +static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID); +static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID); +static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID); +/* + * Trusted key certificate + */ +static const auth_img_desc_t trusted_key_cert = { + .img_id = TRUSTED_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = NULL, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &subject_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &trusted_nv_ctr, + .plat_nv_ctr = &trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &trusted_world_pk, + .data = { + .ptr = (void *)trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + }, + [1] = { + .type_desc = &non_trusted_world_pk, + .data = { + .ptr = (void *)non_trusted_world_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +/* + * Non-Trusted Firmware + */ +static const auth_img_desc_t non_trusted_fw_key_cert = { + .img_id = NON_TRUSTED_FW_KEY_CERT_ID, + .img_type = IMG_CERT, + .parent = &trusted_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &non_trusted_world_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_fw_content_pk, + .data = { + .ptr = (void *)content_pk_buf, + .len = (unsigned int)PK_DER_LEN + } + } + } +}; +static const auth_img_desc_t non_trusted_fw_content_cert = { + .img_id = NON_TRUSTED_FW_CONTENT_CERT_ID, + .img_type = IMG_CERT, + .parent = &non_trusted_fw_key_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_SIG, + .param.sig = { + .pk = &nt_fw_content_pk, + .sig = &sig, + .alg = &sig_alg, + .data = &raw_data + } + }, + [1] = { + .type = AUTH_METHOD_NV_CTR, + .param.nv_ctr = { + .cert_nv_ctr = &non_trusted_nv_ctr, + .plat_nv_ctr = &non_trusted_nv_ctr + } + } + }, + .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) { + [0] = { + .type_desc = &nt_world_bl_hash, + .data = { + .ptr = (void *)nt_world_bl_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + }, + [1] = { + .type_desc = &nt_fw_config_hash, + .data = { + .ptr = (void *)nt_fw_config_hash_buf, + .len = (unsigned int)HASH_DER_LEN + } + } + } +}; +static const auth_img_desc_t bl33_image = { + .img_id = BL33_IMAGE_ID, + .img_type = IMG_RAW, + .parent = &non_trusted_fw_content_cert, + .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { + [0] = { + .type = AUTH_METHOD_HASH, + .param.hash = { + .data = &raw_data, + .hash = &nt_world_bl_hash + } + } + } +}; + +static const auth_img_desc_t * const cot_desc[] = { + [TRUSTED_KEY_CERT_ID] = &trusted_key_cert, + [NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert, + [NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert, + [BL33_IMAGE_ID] = &bl33_image, +}; + +/* Register the CoT in the authentication module */ +REGISTER_COT(cot_desc); diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 549ae6600..72b87c8b9 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -233,8 +233,10 @@ void dcsw_op_all(u_register_t op_type); void disable_mmu_el1(void); void disable_mmu_el3(void); +void disable_mpu_el2(void); void disable_mmu_icache_el1(void); void disable_mmu_icache_el3(void); +void disable_mpu_icache_el2(void); /******************************************************************************* * Misc. accessor prototypes diff --git a/include/lib/xlat_mpu/xlat_mpu.h b/include/lib/xlat_mpu/xlat_mpu.h new file mode 100644 index 000000000..252b92c85 --- /dev/null +++ b/include/lib/xlat_mpu/xlat_mpu.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef XLAT_MPU_H +#define XLAT_MPU_H + +#ifndef __ASSEMBLER__ + +#include + +#define XLAT_TABLES_LIB_V2 1 + +void enable_mpu_el2(unsigned int flags); +void enable_mpu_direct_el2(unsigned int flags); + +/* + * Function to wipe clean and disable all MPU regions. This function expects + * that the MPU has already been turned off, and caching concerns addressed, + * but it nevertheless also explicitly turns off the MPU. + */ +void clear_all_mpu_regions(void); + +#endif /* __ASSEMBLER__ */ +#endif /* XLAT_MPU_H */ diff --git a/include/plat/arm/board/fvp_r/fvp_r_bl1.h b/include/plat/arm/board/fvp_r/fvp_r_bl1.h new file mode 100644 index 000000000..0b41e672f --- /dev/null +++ b/include/plat/arm/board/fvp_r/fvp_r_bl1.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FVP_R_BL1_H +#define FVP_R_BL1_H + +void bl1_load_bl33(void); +void bl1_transfer_bl33(void); + +#endif /* FVP_R_BL1_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 08f7ff980..7cc215f22 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -321,31 +321,31 @@ /* Memory mapped Generic timer interfaces */ #ifdef PLAT_ARM_SYS_CNTCTL_BASE -#define ARM_SYS_CNTCTL_BASE PLAT_ARM_SYS_CNTCTL_BASE +#define ARM_SYS_CNTCTL_BASE PLAT_ARM_SYS_CNTCTL_BASE #else #define ARM_SYS_CNTCTL_BASE UL(0x2a430000) #endif #ifdef PLAT_ARM_SYS_CNTREAD_BASE -#define ARM_SYS_CNTREAD_BASE PLAT_ARM_SYS_CNTREAD_BASE +#define ARM_SYS_CNTREAD_BASE PLAT_ARM_SYS_CNTREAD_BASE #else #define ARM_SYS_CNTREAD_BASE UL(0x2a800000) #endif #ifdef PLAT_ARM_SYS_TIMCTL_BASE -#define ARM_SYS_TIMCTL_BASE PLAT_ARM_SYS_TIMCTL_BASE +#define ARM_SYS_TIMCTL_BASE PLAT_ARM_SYS_TIMCTL_BASE #else #define ARM_SYS_TIMCTL_BASE UL(0x2a810000) #endif #ifdef PLAT_ARM_SYS_CNT_BASE_S -#define ARM_SYS_CNT_BASE_S PLAT_ARM_SYS_CNT_BASE_S +#define ARM_SYS_CNT_BASE_S PLAT_ARM_SYS_CNT_BASE_S #else #define ARM_SYS_CNT_BASE_S UL(0x2a820000) #endif #ifdef PLAT_ARM_SYS_CNT_BASE_NS -#define ARM_SYS_CNT_BASE_NS PLAT_ARM_SYS_CNT_BASE_NS +#define ARM_SYS_CNT_BASE_NS PLAT_ARM_SYS_CNT_BASE_NS #else #define ARM_SYS_CNT_BASE_NS UL(0x2a830000) #endif @@ -354,7 +354,7 @@ /* Trusted Watchdog constants */ #ifdef PLAT_ARM_SP805_TWDG_BASE -#define ARM_SP805_TWDG_BASE PLAT_ARM_SP805_TWDG_BASE +#define ARM_SP805_TWDG_BASE PLAT_ARM_SP805_TWDG_BASE #else #define ARM_SP805_TWDG_BASE UL(0x2a490000) #endif @@ -415,9 +415,14 @@ * addresses. ******************************************************************************/ #define BL1_RO_BASE PLAT_ARM_TRUSTED_ROM_BASE +#ifdef PLAT_BL1_RO_LIMIT +#define BL1_RO_LIMIT PLAT_BL1_RO_LIMIT +#else #define BL1_RO_LIMIT (PLAT_ARM_TRUSTED_ROM_BASE \ + (PLAT_ARM_TRUSTED_ROM_SIZE - \ PLAT_ARM_MAX_ROMLIB_RO_SIZE)) +#endif + /* * Put BL1 RW at the top of the Trusted SRAM. */ diff --git a/lib/xlat_mpu/xlat_mpu.h b/lib/xlat_mpu/xlat_mpu.h deleted file mode 100644 index f46805a42..000000000 --- a/lib/xlat_mpu/xlat_mpu.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef XLAT_MPU_H -#define XLAT_MPU_H - -#define XLAT_TABLES_LIB_V2 1 - -void enable_mpu_el2(unsigned int flags); -void enable_mpu_direct_el2(unsigned int flags); - -/* - * Function to wipe clean and disable all MPU regions. This function expects - * that the MPU has already been turned off, and caching concerns addressed, - * but it nevertheless also explicitly turns off the MPU. - */ -void clear_all_mpu_regions(void); - -#endif /* XLAT_MPU_H */ diff --git a/lib/xlat_mpu/xlat_mpu_context.c b/lib/xlat_mpu/xlat_mpu_context.c index 7cb19dbcc..28c463b8c 100644 --- a/lib/xlat_mpu/xlat_mpu_context.c +++ b/lib/xlat_mpu/xlat_mpu_context.c @@ -8,9 +8,9 @@ #include +#include "lib/xlat_mpu/xlat_mpu.h" #include #include -#include "xlat_mpu.h" #include "xlat_mpu_private.h" #include diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index f7cced48b..293e85487 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -68,8 +68,10 @@ $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD # Add the BL2 CoT (image cert) ifeq (${BL2_AT_EL3}, 0) +ifneq (${PLAT},fvp_r) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert)) endif +endif # Add the SCP_BL2 CoT (key cert + img cert) ifneq (${SCP_BL2},) diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c index 1a1851766..7ae853b76 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c @@ -75,20 +75,12 @@ void bl1_prepare_next_image(unsigned int image_id) cm_set_context(&bl1_cpu_context[security_state], security_state); } /* Prepare the SPSR for the next BL image. */ - if ((security_state != SECURE) && (el_implemented(2) != EL_IMPL_NONE)) { - mode = MODE_EL2; - } - next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode, (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); /* Allow platform to make change */ bl1_plat_set_ep_info(image_id, next_bl_ep); - /* Prepare the context for the next BL image. */ - cm_init_my_context(next_bl_ep); - cm_prepare_el2_exit(security_state); - /* Indicate that image is in execution state. */ desc->state = IMAGE_STATE_EXECUTED; diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S index d2e8ac8bf..19a685c1f 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S +++ b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S @@ -5,9 +5,13 @@ */ #include +#include +#include #include +#include .globl bl1_entrypoint + .globl bl1_run_next_image /* ----------------------------------------------------- @@ -54,10 +58,38 @@ func bl1_entrypoint */ bl bl1_main + /* --------------------------------------------- + * Should never reach this point. + * --------------------------------------------- + */ + no_ret plat_panic_handler +endfunc bl1_entrypoint + +func bl1_run_next_image + mov x20,x0 + + /* --------------------------------------------- + * MPU needs to be disabled because both BL1 and BL33 execute + * in EL2, and therefore share the same address space. + * BL33 will initialize the address space according to its + * own requirement. + * --------------------------------------------- + */ + bl disable_mpu_icache_el2 + + /* --------------------------------------------- + * Wipe clean and disable all MPU regions. This function expects + * that the MPU has already been turned off, and caching concerns + * addressed, but it also explicitly turns off the MPU. + * --------------------------------------------- + */ + bl clear_all_mpu_regions + #if ENABLE_PAUTH - /* -------------------------------------------------------------------- - * Disable pointer authentication before jumping to next boot image. - * -------------------------------------------------------------------- + /* --------------------------------------------- + * Disable pointer authentication before jumping + * to next boot image. + * --------------------------------------------- */ bl pauth_disable_el2 #endif /* ENABLE_PAUTH */ @@ -66,5 +98,13 @@ func bl1_entrypoint * Do the transition to next boot image. * -------------------------------------------------- */ - b el2_exit -endfunc bl1_entrypoint + ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] + msr elr_el2, x0 + msr spsr_el2, x1 + + ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] + ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] + ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] + ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] + exception_return +endfunc bl1_run_next_image diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c index b13ce9f0e..2fd0e97eb 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c @@ -19,11 +19,83 @@ #include #include #include +#include #include #include +void bl1_run_next_image(const struct entry_point_info *bl_ep_info); + +/******************************************************************************* + * Function to perform late architectural and platform specific initialization. + * It also queries the platform to load and run next BL image. Only called + * by the primary cpu after a cold boot. + ******************************************************************************/ +void bl1_transfer_bl33(void) +{ + unsigned int image_id; + + /* Get the image id of next image to load and run. */ + image_id = bl1_plat_get_next_image_id(); + +#if ENABLE_PAUTH + /* + * Disable pointer authentication before running next boot image + */ + pauth_disable_el2(); +#endif /* ENABLE_PAUTH */ + +#if !ARM_DISABLE_TRUSTED_WDOG + /* Disable watchdog before leaving BL1 */ + plat_arm_secure_wdt_stop(); +#endif + + bl1_run_next_image(&bl1_plat_get_image_desc(image_id)->ep_info); +} + +/******************************************************************************* + * This function locates and loads the BL33 raw binary image in the trusted SRAM. + * Called by the primary cpu after a cold boot. + * TODO: Add support for alternative image load mechanism e.g using virtio/elf + * loader etc. + ******************************************************************************/ +void bl1_load_bl33(void) +{ + image_desc_t *desc; + image_info_t *info; + int err; + + /* Get the image descriptor */ + desc = bl1_plat_get_image_desc(BL33_IMAGE_ID); + assert(desc != NULL); + + /* Get the image info */ + info = &desc->image_info; + INFO("BL1: Loading BL33\n"); + + err = bl1_plat_handle_pre_image_load(BL33_IMAGE_ID); + if (err != 0) { + ERROR("Failure in pre image load handling of BL33 (%d)\n", err); + plat_error_handler(err); + } + + err = load_auth_image(BL33_IMAGE_ID, info); + if (err != 0) { + ERROR("Failed to load BL33 firmware.\n"); + plat_error_handler(err); + } + + /* Allow platform to handle image information. */ + err = bl1_plat_handle_post_image_load(BL33_IMAGE_ID); + if (err != 0) { + ERROR("Failure in post image load handling of BL33 (%d)\n", err); + plat_error_handler(err); + } + + NOTICE("BL1: Booting BL33\n"); +} + static void bl1_load_bl2(void); #if ENABLE_PAUTH @@ -112,11 +184,11 @@ void bl1_main(void) if (val != 0) { assert(SIZE_FROM_LOG2_WORDS(val) == CACHE_WRITEBACK_GRANULE); } else { - assert(CACHE_WRITEBACK_GRANULE <= MAX_CACHE_LINE_SIZE); + assert(MAX_CACHE_LINE_SIZE >= CACHE_WRITEBACK_GRANULE); } #endif /* ENABLE_ASSERTIONS */ - /* Perform remaining generic architectural setup from EL2 */ + /* Perform remaining generic architectural setup from ELmax */ bl1_arch_setup(); #if TRUSTED_BOARD_BOOT @@ -142,12 +214,17 @@ void bl1_main(void) */ if (image_id == BL2_IMAGE_ID) { bl1_load_bl2(); + } else if (image_id == BL33_IMAGE_ID) { + bl1_load_bl33(); } else { NOTICE("BL1-FWU: *******FWU Process Started*******\n"); } + bl1_prepare_next_image(image_id); console_flush(); + + bl1_transfer_bl33(); } /******************************************************************************* diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c index c6fb25ff1..5e31d39a2 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -13,13 +13,14 @@ #include #include #include +#include +#include #include "fvp_r_private.h" #include #include #include #include - #include #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ @@ -71,6 +72,9 @@ void arm_bl1_early_platform_setup(void) bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE; } +/* Boolean variable to hold condition whether firmware update needed or not */ +static bool is_fwu_needed; + /******************************************************************************* * Perform any BL1 specific platform actions. ******************************************************************************/ @@ -130,6 +134,44 @@ void plat_arm_secure_wdt_stop(void) sp805_stop(ARM_SP805_TWDG_BASE); } +/* + * Perform the platform specific architecture setup shared between + * ARM standard platforms. + */ +void arm_bl1_platform_setup(void) +{ + image_desc_t *desc; + uint32_t fw_config_max_size; + + /* Initialise the IO layer and register platform IO devices */ + plat_arm_io_setup(); + + /* Check if we need FWU before further processing */ + is_fwu_needed = plat_arm_bl1_fwu_needed(); + if (is_fwu_needed) { + ERROR("Skip platform setup as FWU detected\n"); + return; + } + + /* Set global DTB info for fixed fw_config information */ + fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; + set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID); + + desc = bl1_plat_get_image_desc(BL33_IMAGE_ID); + assert(desc != NULL); + + /* + * Allow access to the System counter timer module and program + * counter frequency for non secure images during FWU + */ +#ifdef ARM_SYS_TIMCTL_BASE + arm_configure_sys_timer(); +#endif +#if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER) + write_cntfrq_el0(plat_get_syscnt_freq2()); +#endif +} + void bl1_platform_setup(void) { arm_bl1_platform_setup(); @@ -147,3 +189,61 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) wfi(); } } + +unsigned int bl1_plat_get_next_image_id(void) +{ + return is_fwu_needed ? NS_BL1U_IMAGE_ID : BL33_IMAGE_ID; +} + +/* + * Returns BL33 image details. + */ +struct image_desc *bl1_plat_get_image_desc(unsigned int image_id) +{ + static image_desc_t bl33_img_desc = BL33_IMAGE_DESC; + + return &bl33_img_desc; +} + +/* + * This function populates the default arguments to BL33. + * The BL33 memory layout structure is allocated and the + * calculated layout is populated in arg1 to BL33. + */ +int bl1_plat_handle_post_image_load(unsigned int image_id) +{ + meminfo_t *bl33_secram_layout; + meminfo_t *bl1_secram_layout; + image_desc_t *image_desc; + entry_point_info_t *ep_info; + + if (image_id != BL33_IMAGE_ID) { + return 0; + } + /* Get the image descriptor */ + image_desc = bl1_plat_get_image_desc(BL33_IMAGE_ID); + assert(image_desc != NULL); + + /* Get the entry point info */ + ep_info = &image_desc->ep_info; + + /* Find out how much free trusted ram remains after BL1 load */ + bl1_secram_layout = bl1_plat_sec_mem_layout(); + + /* + * Create a new layout of memory for BL33 as seen by BL1 i.e. + * tell it the amount of total and free memory available. + * This layout is created at the first free address visible + * to BL33. BL33 will read the memory layout before using its + * memory for other purposes. + */ + bl33_secram_layout = (meminfo_t *) bl1_secram_layout->total_base; + + bl1_calc_bl2_mem_layout(bl1_secram_layout, bl33_secram_layout); + + ep_info->args.arg1 = (uintptr_t)bl33_secram_layout; + + VERBOSE("BL1: BL3 memory layout address = %p\n", + (void *) bl33_secram_layout); + return 0; +} diff --git a/plat/arm/board/fvp_r/fvp_r_common.c b/plat/arm/board/fvp_r/fvp_r_common.c index a9316a1a1..bce943dad 100644 --- a/plat/arm/board/fvp_r/fvp_r_common.c +++ b/plat/arm/board/fvp_r/fvp_r_common.c @@ -73,8 +73,6 @@ const mmap_region_t plat_arm_mmap[] = { #if TRUSTED_BOARD_BOOT /* To access the Root of Trust Public Key registers. */ MAP_DEVICE2, - /* Map DRAM to authenticate NS_BL2U image. */ - ARM_MAP_NS_DRAM1, #endif {0} }; diff --git a/plat/arm/board/fvp_r/fvp_r_err.c b/plat/arm/board/fvp_r/fvp_r_err.c index 0f7aeac02..7ee752b86 100644 --- a/plat/arm/board/fvp_r/fvp_r_err.c +++ b/plat/arm/board/fvp_r/fvp_r_err.c @@ -24,8 +24,8 @@ __dead2 void plat_arm_error_handler(int err) case -EAUTH: /* Image load or authentication error. Erase the ToC */ INFO("Erasing FIP ToC from flash...\n"); - (void)nor_unlock(PLAT_ARM_FIP_BASE); - ret = nor_word_program(PLAT_ARM_FIP_BASE, 0); + (void)nor_unlock(PLAT_ARM_FLASH_IMAGE_BASE); + ret = nor_word_program(PLAT_ARM_FLASH_IMAGE_BASE, 0); if (ret != 0) { ERROR("Cannot erase ToC\n"); } else { diff --git a/plat/arm/board/fvp_r/fvp_r_io_storage.c b/plat/arm/board/fvp_r/fvp_r_io_storage.c index 630d93a10..3b44828f0 100644 --- a/plat/arm/board/fvp_r/fvp_r_io_storage.c +++ b/plat/arm/board/fvp_r/fvp_r_io_storage.c @@ -15,17 +15,11 @@ #include /* Semihosting filenames */ -#define TB_FW_CONFIG_NAME "fvp_tb_fw_config.dtb" -#define HW_CONFIG_NAME "hw_config.dtb" +#define BL33_IMAGE_NAME "bl33.bin" #if TRUSTED_BOARD_BOOT -#define TRUSTED_BOOT_FW_CERT_NAME "tb_fw.crt" #define TRUSTED_KEY_CERT_NAME "trusted_key.crt" -#define SOC_FW_KEY_CERT_NAME "soc_fw_key.crt" -#define TOS_FW_KEY_CERT_NAME "tos_fw_key.crt" #define NT_FW_KEY_CERT_NAME "nt_fw_key.crt" -#define SOC_FW_CONTENT_CERT_NAME "soc_fw_content.crt" -#define TOS_FW_CONTENT_CERT_NAME "tos_fw_content.crt" #define NT_FW_CONTENT_CERT_NAME "nt_fw_content.crt" #endif /* TRUSTED_BOARD_BOOT */ @@ -34,12 +28,8 @@ static const io_dev_connector_t *sh_dev_con; static uintptr_t sh_dev_handle; static const io_file_spec_t sh_file_spec[] = { - [TB_FW_CONFIG_ID] = { - .path = TB_FW_CONFIG_NAME, - .mode = FOPEN_MODE_RB - }, - [HW_CONFIG_ID] = { - .path = HW_CONFIG_NAME, + [BL33_IMAGE_ID] = { + .path = BL33_IMAGE_NAME, .mode = FOPEN_MODE_RB }, #if TRUSTED_BOARD_BOOT diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h index 725d13194..4a6b4416b 100644 --- a/plat/arm/board/fvp_r/include/platform_def.h +++ b/plat/arm/board/fvp_r/include/platform_def.h @@ -9,6 +9,18 @@ #define PLAT_V2M_OFFSET 0x80000000 +#define BL33_IMAGE_DESC { \ + .image_id = BL33_IMAGE_ID, \ + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, \ + VERSION_2, image_info_t, 0), \ + .image_info.image_base = PLAT_ARM_DRAM1_BASE + 0x1000, \ + .image_info.image_max_size = UL(0x3ffff000), \ + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, \ + VERSION_2, entry_point_info_t, SECURE | EXECUTABLE),\ + .ep_info.pc = PLAT_ARM_DRAM1_BASE + 0x1000, \ + .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), \ +} + #include "../fvp_r_def.h" #include #include @@ -60,12 +72,16 @@ #define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ /* These two are defined thus in arm_def.h, but doesn't seem to see it... */ -#undef BL1_RO_BASE -#define BL1_RO_BASE PLAT_ARM_TRUSTED_ROM_BASE -#undef BL1_RO_LIMIT -#define BL1_RO_LIMIT (BL1_RO_BASE \ +#define PLAT_BL1_RO_LIMIT (BL1_RO_BASE \ + PLAT_ARM_TRUSTED_ROM_SIZE) +#define PLAT_ARM_SYS_CNTCTL_BASE UL(0xaa430000) +#define PLAT_ARM_SYS_CNTREAD_BASE UL(0xaa800000) +#define PLAT_ARM_SYS_TIMCTL_BASE UL(0xaa810000) +#define PLAT_ARM_SYS_CNT_BASE_S UL(0xaa820000) +#define PLAT_ARM_SYS_CNT_BASE_NS UL(0xaa830000) +#define PLAT_ARM_SP805_TWDG_BASE UL(0xaa490000) + /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) @@ -84,9 +100,10 @@ #define V2M_FVP_R_SYSREGS_BASE UL(0x9c010000) /* - * Load address of BL33 for this platform port + * Load address of BL33 for this platform port, + * U-Boot specifically must be loaded at a 4K aligned address. */ -#define PLAT_ARM_NS_IMAGE_BASE (ARM_DRAM1_BASE + UL(0x8000000)) +#define PLAT_ARM_NS_IMAGE_BASE (PLAT_ARM_DRAM1_BASE + 0x1000) /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the @@ -103,13 +120,6 @@ # define ALL_MPU_EL2_REGIONS_USED 0xffffffff /* this is the PRENR_EL2 value if all MPU regions are in use */ -/* - * These nominally reserve the last block of flash for PSCI MEM PROTECT flag, - * but no PSCI in FVP_R platform, so reserve nothing: - */ -#define PLAT_ARM_FLASH_IMAGE_BASE V2M_FLASH0_BASE -#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE 0 - /* * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size * plus a little space for growth. @@ -165,9 +175,12 @@ #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 -/* Reserve the last block of flash for PSCI MEM PROTECT flag */ -#define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE -#define PLAT_ARM_FIP_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) +/* + * These nominally reserve the last block of flash for PSCI MEM PROTECT flag, + * but no PSCI in FVP_R platform, so reserve nothing: + */ +#define PLAT_ARM_FLASH_IMAGE_BASE (PLAT_ARM_DRAM1_BASE + UL(0x40000000)) +#define PLAT_ARM_FLASH_IMAGE_MAX_SIZE (PLAT_ARM_DRAM1_SIZE - UL(0x40000000)) #define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE #define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk index a755432e8..39509dd7e 100644 --- a/plat/arm/board/fvp_r/platform.mk +++ b/plat/arm/board/fvp_r/platform.mk @@ -11,7 +11,8 @@ ARCH := aarch64 override NEED_BL2 := no override NEED_BL2U := no override NEED_BL31 := no -override NEED_BL33 := no + +override CTX_INCLUDE_AARCH32_REGS := 0 # Default cluster count for FVP_R FVP_R_CLUSTER_COUNT := 2 @@ -25,9 +26,6 @@ FVP_R_MAX_PE_PER_CPU := 1 # Use MPU-based memory management: XLAT_MPU_LIB_V1 := 1 -# Need to revisit this for FVP_R -FVP_R_DT_PREFIX := fvp-base-gicv3-psci - # Pass FVP_R_CLUSTER_COUNT to the build system. $(eval $(call add_define,FVP_R_CLUSTER_COUNT)) @@ -87,7 +85,7 @@ BL1_SOURCES += drivers/arm/sp805/sp805.c \ plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c \ plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S \ plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S \ - plat/arm/board/fvp_r/fvp_r_bl1_main.c \ + plat/arm/board/fvp_r/fvp_r_bl1_main.c \ plat/arm/board/fvp_r/fvp_r_context.S \ plat/arm/board/fvp_r/fvp_r_debug.S \ plat/arm/board/fvp_r/fvp_r_helpers.S \ @@ -115,28 +113,13 @@ ifneq (${BL2_AT_EL3}, 0) override BL1_SOURCES = endif -# Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) -ifdef UNIX_MK -FVP_R_HW_CONFIG_DTS := fdts/${FVP_R_DT_PREFIX}.dts -FDT_SOURCES += $(addprefix plat/arm/board/fvp_r/fdts/, \ - ${PLAT}_fw_config.dts \ - ${PLAT}_nt_fw_config.dts \ - ) - -FVP_R_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_fw_config.dtb -FVP_R_NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb - -# Add the FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_FW_CONFIG},--fw-config,${FVP_R_FW_CONFIG})) -# Add the NT_FW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_NT_FW_CONFIG},--nt-fw-config,${FVP_R_NT_FW_CONFIG})) +include plat/arm/board/common/board_common.mk +include plat/arm/common/arm_common.mk -FDT_SOURCES += ${FVP_R_HW_CONFIG_DTS} -$(eval FVP_R_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_R_HW_CONFIG_DTS))) +ifeq (${TRUSTED_BOARD_BOOT}, 1) +BL1_SOURCES += plat/arm/board/fvp_r/fvp_r_trusted_boot.c -# Add the HW_CONFIG to FIP and specify the same to certtool -$(eval $(call TOOL_ADD_PAYLOAD,${FVP_R_HW_CONFIG},--hw-config,${FVP_R_HW_CONFIG})) +# FVP being a development platform, enable capability to disable Authentication +# dynamically if TRUSTED_BOARD_BOOT is set. +DYN_DISABLE_AUTH := 1 endif - -include plat/arm/board/common/board_common.mk -include plat/arm/common/arm_common.mk diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c index 124c1af53..ce2c35699 100644 --- a/plat/arm/common/arm_bl1_fwu.c +++ b/plat/arm/common/arm_bl1_fwu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,8 @@ #include #include +#pragma weak bl1_plat_get_image_desc + /* Struct to keep track of usable memory */ typedef struct bl1_mem_info { uintptr_t mem_base; diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index dd8f13bb6..872de3e3d 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -27,6 +27,7 @@ #pragma weak bl1_plat_get_next_image_id #pragma weak plat_arm_bl1_fwu_needed #pragma weak arm_bl1_plat_arch_setup +#pragma weak arm_bl1_platform_setup #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ bl1_tzram_layout.total_base, \ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 4304db43e..dc8c6d01e 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -355,8 +355,13 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) - BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + ifeq (${PLAT},fvp_r) + BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl1_r64.c + else + BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ drivers/auth/tbbr/tbbr_cot_bl1.c + endif ifneq (${COT_DESC_IN_DTB},0) BL2_SOURCES += lib/fconf/fconf_cot_getter.c else -- cgit v1.2.3 From cd12b195e05ecebda267b2a949cd8fa58fa3c69d Mon Sep 17 00:00:00 2001 From: laurenw-arm Date: Thu, 13 May 2021 14:14:55 -0500 Subject: docs: armv8-R aarch64 fvp_r documentation Documenting armv8-R aarch64 fvp_r features, boot sequence, and build procedure. Signed-off-by: Lauren Wehrmeister Change-Id: If75d59acdf0f8a61cea6187967a4c35af2f31c98 --- docs/plat/arm/fvp_r/index.rst | 46 +++++++++++++++++++++++++++++++++++++++++++ docs/plat/arm/index.rst | 3 ++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 docs/plat/arm/fvp_r/index.rst diff --git a/docs/plat/arm/fvp_r/index.rst b/docs/plat/arm/fvp_r/index.rst new file mode 100644 index 000000000..8af16baa2 --- /dev/null +++ b/docs/plat/arm/fvp_r/index.rst @@ -0,0 +1,46 @@ +ARM V8-R64 Fixed Virtual Platform (FVP) +======================================= + +Some of the features of Armv8-R AArch64 FVP platform referenced in Trusted +Boot R-class include: + +- Secure World Support Only +- EL2 as Maximum EL support (No EL3) +- MPU Support only at EL2 +- MPU or MMU Support at EL0/EL1 +- AArch64 Support Only +- Trusted Board Boot + +Further information on v8-R64 FVP is available at `info `_ + +Boot Sequence +------------- + +BL1 –> BL33 + +The execution begins from BL1 which loads the BL33 image, a boot-wrapped (bootloader + Operating System) +Operating System, from FIP to DRAM. + +Build Procedure +~~~~~~~~~~~~~~~ + +- Obtain arm `toolchain `_. + Set the CROSS_COMPILE environment variable to point to the toolchain folder. + +- Build TF-A: + + .. code:: shell + + make PLAT=fvp_r BL33= all fip + + Enable TBBR by adding the following options to the make command: + + .. code:: shell + + MBEDTLS_DIR= \ + TRUSTED_BOARD_BOOT=1 \ + GENERATE_COT=1 \ + ARM_ROTPK_LOCATION=devel_rsa \ + ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem + +*Copyright (c) 2021, Arm Limited. All rights reserved.* diff --git a/docs/plat/arm/index.rst b/docs/plat/arm/index.rst index c834f6ae7..f262dc039 100644 --- a/docs/plat/arm/index.rst +++ b/docs/plat/arm/index.rst @@ -7,6 +7,7 @@ Arm Development Platforms juno/index fvp/index + fvp_r/index fvp-ve/index tc/index arm_fpga/index @@ -20,4 +21,4 @@ such as Juno. -------------- -*Copyright (c) 2021, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2021, Arm Limited. All rights reserved.* -- cgit v1.2.3 From 7bd8dfb85a8bf5c22d6a39f4538b89cc748090d1 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 19 Aug 2021 16:12:50 -0500 Subject: feat(cpu): add support for Hayes CPU This patch adds the basic CPU library code to support the Hayes CPU in TF-A. This CPU is based on the Klein core so that library code has been adapted for use here. Signed-off-by: John Powell Change-Id: If0e0070cfa77fee8f6eebfee13d3c4f209ad84fc --- include/lib/cpus/aarch64/cortex_hayes.h | 23 ++++++++++ lib/cpus/aarch64/cortex_hayes.S | 77 +++++++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 include/lib/cpus/aarch64/cortex_hayes.h create mode 100644 lib/cpus/aarch64/cortex_hayes.S diff --git a/include/lib/cpus/aarch64/cortex_hayes.h b/include/lib/cpus/aarch64/cortex_hayes.h new file mode 100644 index 000000000..82022e9ff --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_hayes.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_HAYES_H +#define CORTEX_HAYES_H + +#define CORTEX_HAYES_MIDR U(0x410FD800) + +/******************************************************************************* + * CPU Extended Control register specific definitions + ******************************************************************************/ +#define CORTEX_HAYES_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define CORTEX_HAYES_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* CORTEX_HAYES_H */ diff --git a/lib/cpus/aarch64/cortex_hayes.S b/lib/cpus/aarch64/cortex_hayes.S new file mode 100644 index 000000000..445a69187 --- /dev/null +++ b/lib/cpus/aarch64/cortex_hayes.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* Hardware handled coherency */ +#if HW_ASSISTED_COHERENCY == 0 +#error "Cortex Hayes must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex Hayes supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* ---------------------------------------------------- + * HW will do the cache maintenance while powering down + * ---------------------------------------------------- + */ +func cortex_hayes_core_pwr_dwn + /* --------------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------------- + */ + mrs x0, CORTEX_HAYES_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_HAYES_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr CORTEX_HAYES_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_hayes_core_pwr_dwn + + /* + * Errata printing function for Cortex Hayes. Must follow AAPCS. + */ +#if REPORT_ERRATA +func cortex_hayes_errata_report + ret +endfunc cortex_hayes_errata_report +#endif + +func cortex_hayes_reset_func + /* Disable speculative loads */ + msr SSBS, xzr + isb + ret +endfunc cortex_hayes_reset_func + + /* --------------------------------------------- + * This function provides Cortex Hayes specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ascii and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.cortex_hayes_regs, "aS" +cortex_hayes_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_hayes_cpu_reg_dump + adr x6, cortex_hayes_regs + mrs x8, CORTEX_HAYES_CPUECTLR_EL1 + ret +endfunc cortex_hayes_cpu_reg_dump + +declare_cpu_ops cortex_hayes, CORTEX_HAYES_MIDR, \ + cortex_hayes_reset_func, \ + cortex_hayes_core_pwr_dwn diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 2f8a65e56..73f09e50c 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -138,7 +138,8 @@ else lib/cpus/aarch64/cortex_demeter.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S \ - lib/cpus/aarch64/cortex_a78c.S + lib/cpus/aarch64/cortex_a78c.S \ + lib/cpus/aarch64/cortex_hayes.S endif # AArch64/AArch32 cores FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ -- cgit v1.2.3 From ff766148b52bfecf09728a83fc3becc7941d943c Mon Sep 17 00:00:00 2001 From: Laurent Carlier Date: Thu, 30 Sep 2021 15:57:09 +0100 Subject: feat(fdt): add for_each_compatible_node macro This macro enables users to go through dts nodes that have a particular compatible string in its node attribute. Signed-off-by: Laurent Carlier Change-Id: Id80cbe6f6057076e0d53905cdc0f9a44e79960f8 --- include/common/fdt_wrappers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index e8b39335d..98e7a3e6f 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -48,4 +48,9 @@ static inline uint32_t fdt_blob_size(const void *dtb) return fdt32_to_cpu(dtb_header[1]); } +#define fdt_for_each_compatible_node(dtb, node, compatible_str) \ +for (node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); \ + node >= 0; \ + node = fdt_node_offset_by_compatible(dtb, node, compatible_str)) + #endif /* FDT_WRAPPERS_H */ -- cgit v1.2.3 From 1c65989e70c9734defc666e824628620b2060b92 Mon Sep 17 00:00:00 2001 From: Laurent Carlier Date: Thu, 16 Sep 2021 15:10:35 +0100 Subject: feat(drivers/arm/ethosn)!: multi-device support Add support for Arm Ethos-N NPU multi-device. The device tree parsing currently only supports one NPU device with multiple cores. To be able to support multi-device NPU configurations this patch adds support for having multiple NPU devices in the device tree. To be able to support multiple NPU devices in the SMC API, it has been changed in an incompatible way so the API version has been bumped. Signed-off-by: Laurent Carlier Change-Id: Ide279ce949bd06e8939268b9601c267e45f3edc3 --- drivers/arm/ethosn/ethosn_smc.c | 58 +++++++------ fdts/juno-ethosn.dtsi | 12 +-- include/drivers/arm/ethosn.h | 8 +- include/plat/arm/common/fconf_ethosn_getter.h | 9 +- plat/arm/common/fconf/fconf_ethosn_getter.c | 114 ++++++++++++++------------ 5 files changed, 112 insertions(+), 89 deletions(-) diff --git a/drivers/arm/ethosn/ethosn_smc.c b/drivers/arm/ethosn/ethosn_smc.c index 299d07c02..60364cdb2 100644 --- a/drivers/arm/ethosn/ethosn_smc.c +++ b/drivers/arm/ethosn/ethosn_smc.c @@ -14,11 +14,10 @@ #include #include -/* Arm Ethos-N NPU (NPU) status */ -#define ETHOSN_STATUS \ - FCONF_GET_PROPERTY(hw_config, ethosn_config, status) - -/* Number of NPU cores available */ +/* + * Number of Arm Ethos-N NPU (NPU) cores available for a + * particular parent device + */ #define ETHOSN_NUM_CORES \ FCONF_GET_PROPERTY(hw_config, ethosn_config, num_cores) @@ -51,6 +50,17 @@ #define SEC_SYSCTRL0_SOFT_RESET U(3U << 29) #define SEC_SYSCTRL0_HARD_RESET U(1U << 31) +static bool ethosn_is_core_addr_valid(uintptr_t core_addr) +{ + for (uint32_t core_idx = 0U; core_idx < ETHOSN_NUM_CORES; core_idx++) { + if (ETHOSN_CORE_ADDR(core_idx) == core_addr) { + return true; + } + } + + return false; +} + static void ethosn_delegate_to_ns(uintptr_t core_addr) { mmio_setbits_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_SECCTLR_REG), @@ -66,9 +76,9 @@ static void ethosn_delegate_to_ns(uintptr_t core_addr) SEC_DEL_ADDR_EXT_VAL); } -static int ethosn_is_sec(void) +static int ethosn_is_sec(uintptr_t core_addr) { - if ((mmio_read_32(ETHOSN_CORE_SEC_REG(ETHOSN_CORE_ADDR(0), SEC_DEL_REG)) + if ((mmio_read_32(ETHOSN_CORE_SEC_REG(core_addr, SEC_DEL_REG)) & SEC_DEL_EXCC_MASK) != 0U) { return 0; } @@ -101,7 +111,7 @@ static bool ethosn_reset(uintptr_t core_addr, int hard_reset) } uintptr_t ethosn_smc_handler(uint32_t smc_fid, - u_register_t core_idx, + u_register_t core_addr, u_register_t x2, u_register_t x3, u_register_t x4, @@ -109,8 +119,8 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, void *handle, u_register_t flags) { - uintptr_t core_addr; int hard_reset = 0; + const uint32_t fid = smc_fid & FUNCID_NUM_MASK; /* Only SiP fast calls are expected */ if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) || @@ -120,7 +130,7 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, /* Truncate parameters to 32-bits for SMC32 */ if (GET_SMC_CC(smc_fid) == SMC_32) { - core_idx &= 0xFFFFFFFF; + core_addr &= 0xFFFFFFFF; x2 &= 0xFFFFFFFF; x3 &= 0xFFFFFFFF; x4 &= 0xFFFFFFFF; @@ -130,33 +140,29 @@ uintptr_t ethosn_smc_handler(uint32_t smc_fid, SMC_RET1(handle, SMC_UNK); } - if (ETHOSN_STATUS == ETHOSN_STATUS_DISABLED) { - WARN("ETHOSN: Arm Ethos-N NPU not available\n"); - SMC_RET1(handle, ETHOSN_NOT_SUPPORTED); - } - - switch (smc_fid & FUNCID_NUM_MASK) { + /* Commands that do not require a valid core address */ + switch (fid) { case ETHOSN_FNUM_VERSION: SMC_RET2(handle, ETHOSN_VERSION_MAJOR, ETHOSN_VERSION_MINOR); + } + + if (!ethosn_is_core_addr_valid(core_addr)) { + WARN("ETHOSN: Unknown core address given to SMC call.\n"); + SMC_RET1(handle, ETHOSN_UNKNOWN_CORE_ADDRESS); + } + + /* Commands that require a valid addr */ + switch (fid) { case ETHOSN_FNUM_IS_SEC: - SMC_RET1(handle, ethosn_is_sec()); + SMC_RET1(handle, ethosn_is_sec(core_addr)); case ETHOSN_FNUM_HARD_RESET: hard_reset = 1; /* Fallthrough */ case ETHOSN_FNUM_SOFT_RESET: - if (core_idx >= ETHOSN_NUM_CORES) { - WARN("ETHOSN: core index out of range\n"); - SMC_RET1(handle, ETHOSN_CORE_IDX_OUT_OF_RANGE); - } - - core_addr = ETHOSN_CORE_ADDR(core_idx); - if (!ethosn_reset(core_addr, hard_reset)) { SMC_RET1(handle, ETHOSN_FAILURE); } - ethosn_delegate_to_ns(core_addr); - SMC_RET1(handle, ETHOSN_SUCCESS); default: SMC_RET1(handle, SMC_UNK); diff --git a/fdts/juno-ethosn.dtsi b/fdts/juno-ethosn.dtsi index 87ab378a2..e2f33550e 100644 --- a/fdts/juno-ethosn.dtsi +++ b/fdts/juno-ethosn.dtsi @@ -4,19 +4,21 @@ * SPDX-License-Identifier: BSD-3-Clause */ +/* + * For examples of multi-core and multi-device NPU, refer to the examples given in the + * Arm Ethos-N NPU driver stack. + * https://github.com/ARM-software/ethos-n-driver-stack + */ + / { #address-cells = <2>; #size-cells = <2>; - ethosn: ethosn@6f300000 { + ethosn0: ethosn@6f300000 { compatible = "ethosn"; reg = <0 0x6f300000 0 0x00100000>; status = "okay"; - /* - * Single-core NPU. For multi-core NPU, additional core nodes - * and reg values must be added. - */ core0 { compatible = "ethosn-core"; status = "okay"; diff --git a/include/drivers/arm/ethosn.h b/include/drivers/arm/ethosn.h index 6de2abb85..931073338 100644 --- a/include/drivers/arm/ethosn.h +++ b/include/drivers/arm/ethosn.h @@ -38,8 +38,8 @@ #define is_ethosn_fid(_fid) (((_fid) & ETHOSN_FID_MASK) == ETHOSN_FID_VALUE) /* Service version */ -#define ETHOSN_VERSION_MAJOR U(0) -#define ETHOSN_VERSION_MINOR U(1) +#define ETHOSN_VERSION_MAJOR U(1) +#define ETHOSN_VERSION_MINOR U(0) /* Return codes for function calls */ #define ETHOSN_SUCCESS 0 @@ -47,10 +47,10 @@ /* -2 Reserved for NOT_REQUIRED */ /* -3 Reserved for INVALID_PARAMETER */ #define ETHOSN_FAILURE -4 -#define ETHOSN_CORE_IDX_OUT_OF_RANGE -5 +#define ETHOSN_UNKNOWN_CORE_ADDRESS -5 uintptr_t ethosn_smc_handler(uint32_t smc_fid, - u_register_t core_idx, + u_register_t core_addr, u_register_t x2, u_register_t x3, u_register_t x4, diff --git a/include/plat/arm/common/fconf_ethosn_getter.h b/include/plat/arm/common/fconf_ethosn_getter.h index 0fd1f025a..fcdc31f8b 100644 --- a/include/plat/arm/common/fconf_ethosn_getter.h +++ b/include/plat/arm/common/fconf_ethosn_getter.h @@ -14,7 +14,7 @@ #define hw_config__ethosn_config_getter(prop) ethosn_config.prop #define hw_config__ethosn_core_addr_getter(idx) __extension__ ({ \ assert(idx < ethosn_config.num_cores); \ - ethosn_config.core_addr[idx]; \ + ethosn_config.core[idx].addr; \ }) #define ETHOSN_STATUS_DISABLED U(0) @@ -22,10 +22,13 @@ #define ETHOSN_CORE_NUM_MAX U(64) +struct ethosn_core_t { + uint64_t addr; +}; + struct ethosn_config_t { - uint8_t status; uint32_t num_cores; - uint64_t core_addr[ETHOSN_CORE_NUM_MAX]; + struct ethosn_core_t core[ETHOSN_CORE_NUM_MAX]; }; int fconf_populate_arm_ethosn(uintptr_t config); diff --git a/plat/arm/common/fconf/fconf_ethosn_getter.c b/plat/arm/common/fconf/fconf_ethosn_getter.c index 1ba9f3a23..0af1a20fb 100644 --- a/plat/arm/common/fconf/fconf_ethosn_getter.c +++ b/plat/arm/common/fconf/fconf_ethosn_getter.c @@ -12,7 +12,7 @@ #include #include -struct ethosn_config_t ethosn_config; +struct ethosn_config_t ethosn_config = {.num_cores = 0}; static uint8_t fdt_node_get_status(const void *fdt, int node) { @@ -33,74 +33,86 @@ static uint8_t fdt_node_get_status(const void *fdt, int node) int fconf_populate_ethosn_config(uintptr_t config) { int ethosn_node; - int sub_node; - uint8_t ethosn_status; - uint32_t core_count = 0U; - uint32_t core_addr_idx = 0U; const void *hw_conf_dtb = (const void *)config; /* Find offset to node with 'ethosn' compatible property */ - ethosn_node = fdt_node_offset_by_compatible(hw_conf_dtb, -1, "ethosn"); - if (ethosn_node < 0) { - ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n"); - return ethosn_node; - } - - /* If the Arm Ethos-N NPU is disabled the core check can be skipped */ - ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node); - if (ethosn_status == ETHOSN_STATUS_DISABLED) { - return 0; - } + INFO("Probing Arm Ethos-N NPU\n"); + uint32_t total_core_count = 0U; - fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) { - int err; - uintptr_t addr; - uint8_t status; + fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") { + int sub_node; + uint8_t ethosn_status; + uint32_t device_core_count = 0U; - /* Check that the sub node is "ethosn-core" compatible */ - if (fdt_node_check_compatible(hw_conf_dtb, sub_node, - "ethosn-core") != 0) { - /* Ignore incompatible sub node */ + /* If the Arm Ethos-N NPU is disabled the core check can be skipped */ + ethosn_status = fdt_node_get_status(hw_conf_dtb, ethosn_node); + if (ethosn_status == ETHOSN_STATUS_DISABLED) { continue; } - /* Including disabled cores */ - if (core_addr_idx >= ETHOSN_CORE_NUM_MAX) { - ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n"); - return -1; + fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) { + int err; + uintptr_t core_addr; + uint8_t core_status; + + if (total_core_count >= ETHOSN_CORE_NUM_MAX) { + ERROR("FCONF: Reached max number of Arm Ethos-N NPU cores\n"); + return -FDT_ERR_BADSTRUCTURE; + } + + /* Check that the sub node is "ethosn-core" compatible */ + if (fdt_node_check_compatible(hw_conf_dtb, + sub_node, + "ethosn-core") != 0) { + /* Ignore incompatible sub node */ + continue; + } + + core_status = fdt_node_get_status(hw_conf_dtb, sub_node); + if (core_status == ETHOSN_STATUS_DISABLED) { + continue; + } + + err = fdt_get_reg_props_by_index(hw_conf_dtb, + ethosn_node, + device_core_count, + &core_addr, + NULL); + if (err < 0) { + ERROR( + "FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n", + device_core_count); + return err; + } + + INFO("NPU core probed at address 0x%lx\n", core_addr); + ethosn_config.core[total_core_count].addr = core_addr; + total_core_count++; + device_core_count++; } - status = fdt_node_get_status(hw_conf_dtb, ethosn_node); - if (status == ETHOSN_STATUS_DISABLED) { - ++core_addr_idx; - continue; + if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) { + ERROR("FCONF: Failed to parse sub nodes\n"); + return -FDT_ERR_BADSTRUCTURE; } - err = fdt_get_reg_props_by_index(hw_conf_dtb, ethosn_node, - core_addr_idx, &addr, NULL); - if (err < 0) { - ERROR("FCONF: Failed to read reg property for Arm Ethos-N NPU core %u\n", - core_addr_idx); - return err; + if (device_core_count == 0U) { + ERROR( + "FCONF: Enabled Arm Ethos-N NPU device must have at least one enabled core\n"); + return -FDT_ERR_BADSTRUCTURE; } - - ethosn_config.core_addr[core_count++] = addr; - ++core_addr_idx; } - if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) { - ERROR("FCONF: Failed to parse sub nodes\n"); - return sub_node; + if (total_core_count == 0U) { + ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n"); + return -FDT_ERR_BADSTRUCTURE; } - /* The Arm Ethos-N NPU can't be used if no cores were found */ - if (core_count == 0) { - ERROR("FCONF: No Arm Ethos-N NPU cores found\n"); - return -1; - } + ethosn_config.num_cores = total_core_count; - ethosn_config.num_cores = core_count; - ethosn_config.status = ethosn_status; + INFO("%d NPU core%s probed\n", + ethosn_config.num_cores, + ethosn_config.num_cores > 1 ? "s" : ""); return 0; } -- cgit v1.2.3 From 744bdbf732ffd2abf84b2431624051e93bc29f7b Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Wed, 22 Sep 2021 12:35:03 -0700 Subject: fix(errata): workaround for Cortex-A710 erratum 2058056 Cortex-A710 erratum 2058056 is a Cat B erratum that applies to revisions r0p0, r1p0, and r2p0. It is still open. The workaround is to write the value 4'b1001 to the PF_MODE bits in the IMP_CPUECTLR2_EL1 register which will place the data prefetcher in the most conservative mode instead of disabling it. SDEN can be found here: https://developer.arm.com/documentation/SDEN1775101/latest Signed-off-by: nayanpatel-arm Change-Id: I7ce5181b3b469fbbb16501e633116e119b8bf4f1 --- docs/design/cpu-specific-build-macros.rst | 4 ++++ include/lib/cpus/aarch64/cortex_a710.h | 10 ++++++++- lib/cpus/aarch64/cortex_a710.S | 34 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 80e7821f7..362f19df1 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -393,6 +393,10 @@ For Cortex-A710, the following errata build flags are defined : Cortex-A710 CPU. This needs to be enabled for revision r2p0 of the CPU and is still open. +- ``ERRATA_A710_2058056``: This applies errata 2058056 workaround to + Cortex-A710 CPU. This needs to be enabled for revisions r0p0, r1p0 and r2p0 + of the CPU and is still open. + For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2 diff --git a/include/lib/cpus/aarch64/cortex_a710.h b/include/lib/cpus/aarch64/cortex_a710.h index 19394ba10..d2bc146d9 100644 --- a/include/lib/cpus/aarch64/cortex_a710.h +++ b/include/lib/cpus/aarch64/cortex_a710.h @@ -25,7 +25,7 @@ * CPU Auxiliary Control register specific definitions. ******************************************************************************/ #define CORTEX_A710_CPUACTLR_EL1 S3_0_C15_C1_0 -#define CORTEX_A710_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) +#define CORTEX_A710_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) /******************************************************************************* * CPU Auxiliary Control register specific definitions. @@ -33,4 +33,12 @@ #define CORTEX_A710_CPUACTLR5_EL1 S3_0_C15_C8_0 #define CORTEX_A710_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13) +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define CORTEX_A710_CPUECTLR2_EL1 S3_0_C15_C1_5 +#define CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV ULL(9) +#define CPUECTLR2_EL1_PF_MODE_LSB U(11) +#define CPUECTLR2_EL1_PF_MODE_WIDTH U(4) + #endif /* CORTEX_A710_H */ diff --git a/lib/cpus/aarch64/cortex_a710.S b/lib/cpus/aarch64/cortex_a710.S index f6a4209c4..7d7fbd888 100644 --- a/lib/cpus/aarch64/cortex_a710.S +++ b/lib/cpus/aarch64/cortex_a710.S @@ -188,6 +188,34 @@ func check_errata_2083908 b cpu_rev_var_range endfunc check_errata_2083908 +/* --------------------------------------------------------------------- + * Errata Workaround for Cortex-A710 Erratum 2058056. + * This applies to revisions r0p0, r1p0 and r2p0 of Cortex-A710 and is still + * open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * --------------------------------------------------------------------- + */ +func errata_a710_2058056_wa + /* Compare x0 against revision r2p0 */ + mov x17, x30 + bl check_errata_2058056 + cbz x0, 1f + mrs x1, CORTEX_A710_CPUECTLR2_EL1 + mov x0, #CORTEX_A710_CPUECTLR2_EL1_PF_MODE_CNSRV + bfi x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH + msr CORTEX_A710_CPUECTLR2_EL1, x1 +1: + ret x17 +endfunc errata_a710_2058056_wa + +func check_errata_2058056 + /* Applies to r0p0, r1p0 and r2p0 */ + mov x1, #0x20 + b cpu_rev_var_ls +endfunc check_errata_2058056 + /* ---------------------------------------------------- * HW will do the cache maintenance while powering down * ---------------------------------------------------- @@ -223,6 +251,7 @@ func cortex_a710_errata_report report_errata ERRATA_A710_2055002, cortex_a710, 2055002 report_errata ERRATA_A710_2017096, cortex_a710, 2017096 report_errata ERRATA_A710_2083908, cortex_a710, 2083908 + report_errata ERRATA_A710_2058056, cortex_a710, 2058056 ldp x8, x30, [sp], #16 ret @@ -262,6 +291,11 @@ func cortex_a710_reset_func mov x0, x18 bl errata_a710_2083908_wa #endif + +#if ERRATA_A710_2058056 + mov x0, x18 + bl errata_a710_2058056_wa +#endif isb ret x19 endfunc cortex_a710_reset_func diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index fd34dcb09..d67223ce9 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -429,6 +429,10 @@ ERRATA_A710_2081180 ?=0 # to revision r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2083908 ?=0 +# Flag to apply erratum 2058056 workaround during reset. This erratum applies +# to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open. +ERRATA_A710_2058056 ?=0 + # Flag to apply erratum 2067956 workaround during reset. This erratum applies # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2067956 ?=0 @@ -814,6 +818,10 @@ $(eval $(call add_define,ERRATA_A710_2081180)) $(eval $(call assert_boolean,ERRATA_A710_2083908)) $(eval $(call add_define,ERRATA_A710_2083908)) +# Process ERRATA_A710_2058056 flag +$(eval $(call assert_boolean,ERRATA_A710_2058056)) +$(eval $(call add_define,ERRATA_A710_2058056)) + # Process ERRATA_N2_2067956 flag $(eval $(call assert_boolean,ERRATA_N2_2067956)) $(eval $(call add_define,ERRATA_N2_2067956)) -- cgit v1.2.3 From ef8f0c52ddf83e815a029319971682d7a26b6a6f Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Tue, 28 Sep 2021 09:46:45 -0700 Subject: fix(errata): workaround for Neoverse-N2 erratum 2138953 Neoverse-N2 erratum 2138953 is a Cat B erratum that applies to revision r0p0 of CPU. It is still open. The workaround is to write the value 4'b1001 to the PF_MODE bits in the IMP_CPUECTLR2_EL1 register which will place the data prefetcher in the most conservative mode instead of disabling it. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest Signed-off-by: nayanpatel-arm Change-Id: Ife0a4bece7ccf83cc99c1d5f5b5a43084bb69d64 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/neoverse_n2.h | 32 ++++++++++++++++---------- lib/cpus/aarch64/neoverse_n2.S | 37 ++++++++++++++++++++++++++++++- lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index bde6d97e6..9676ae787 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -403,6 +403,9 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2138956``: This applies errata 2138956 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. + DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h index 948f96511..f414cb53c 100644 --- a/include/lib/cpus/aarch64/neoverse_n2.h +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -8,37 +8,45 @@ #define NEOVERSE_N2_H /* Neoverse N2 ID register for revision r0p0 */ -#define NEOVERSE_N2_MIDR U(0x410FD490) +#define NEOVERSE_N2_MIDR U(0x410FD490) /******************************************************************************* * CPU Power control register ******************************************************************************/ -#define NEOVERSE_N2_CPUPWRCTLR_EL1 S3_0_C15_C2_7 -#define NEOVERSE_N2_CORE_PWRDN_EN_BIT (ULL(1) << 0) +#define NEOVERSE_N2_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define NEOVERSE_N2_CORE_PWRDN_EN_BIT (ULL(1) << 0) /******************************************************************************* * CPU Extended Control register specific definitions. ******************************************************************************/ -#define NEOVERSE_N2_CPUECTLR_EL1 S3_0_C15_C1_4 -#define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0) -#define NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8) +#define NEOVERSE_N2_CPUECTLR_EL1 S3_0_C15_C1_4 +#define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT (ULL(1) << 0) +#define NEOVERSE_N2_CPUECTLR_EL1_PFSTIDIS_BIT (ULL(1) << 8) /******************************************************************************* * CPU Auxiliary Control register specific definitions. ******************************************************************************/ -#define NEOVERSE_N2_CPUACTLR_EL1 S3_0_C15_C1_0 -#define NEOVERSE_N2_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) +#define NEOVERSE_N2_CPUACTLR_EL1 S3_0_C15_C1_0 +#define NEOVERSE_N2_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) /******************************************************************************* * CPU Auxiliary Control register 2 specific definitions. ******************************************************************************/ -#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1 -#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) +#define NEOVERSE_N2_CPUACTLR2_EL1 S3_0_C15_C1_1 +#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2) /******************************************************************************* * CPU Auxiliary Control register 5 specific definitions. ******************************************************************************/ -#define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0 -#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44) +#define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0 +#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44) + +/******************************************************************************* + * CPU Auxiliary Control register specific definitions. + ******************************************************************************/ +#define NEOVERSE_N2_CPUECTLR2_EL1 S3_0_C15_C1_5 +#define NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV ULL(9) +#define CPUECTLR2_EL1_PF_MODE_LSB U(11) +#define CPUECTLR2_EL1_PF_MODE_WIDTH U(4) #endif /* NEOVERSE_N2_H */ diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index 9e7bbf7e6..330cc596a 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -183,6 +183,35 @@ func check_errata_2138956 b cpu_rev_var_ls endfunc check_errata_2138956 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2138953. + * This applies to revision r0p0 of Neoverse N2. it is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2138953_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2138953 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mrs x1, NEOVERSE_N2_CPUECTLR2_EL1 + mov x0, #NEOVERSE_N2_CPUECTLR2_EL1_PF_MODE_CNSRV + bfi x1, x0, #CPUECTLR2_EL1_PF_MODE_LSB, #CPUECTLR2_EL1_PF_MODE_WIDTH + msr NEOVERSE_N2_CPUECTLR2_EL1, x1 +1: + ret x17 +endfunc errata_n2_2138953_wa + +func check_errata_2138953 + /* Applies to r0p0 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2138953 + /* ------------------------------------------- * The CPU Ops reset function for Neoverse N2. * ------------------------------------------- @@ -224,6 +253,11 @@ func neoverse_n2_reset_func bl errata_n2_2138956_wa #endif +#if ERRATA_N2_2138953 + mov x0, x18 + bl errata_n2_2138953_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, cptr_el3 @@ -287,8 +321,9 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2002655, neoverse_n2, 2002655 report_errata ERRATA_N2_2067956, neoverse_n2, 2067956 report_errata ERRATA_N2_2025414, neoverse_n2, 2025414 - report_errata ERRATA_N2_2189731, neoverse_n2, 2189731 + report_errata ERRATA_N2_2189731, neoverse_n2, 2189731 report_errata ERRATA_N2_2138956, neoverse_n2, 2138956 + report_errata ERRATA_N2_2138953, neoverse_n2, 2138953 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 6103a5a7b..1d470e20b 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -441,6 +441,10 @@ ERRATA_N2_2189731 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2138956 ?=0 +# Flag to apply erratum 2138953 workaround during reset. This erratum applies +# to revision r0p0 of the Neoverse N2 cpu and is still open. +ERRATA_N2_2138953 ?=0 + # Flag to apply erratum 2055002 workaround during reset. This erratum applies # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2055002 ?=0 @@ -822,6 +826,10 @@ $(eval $(call add_define,ERRATA_N2_2189731)) $(eval $(call assert_boolean,ERRATA_N2_2138956)) $(eval $(call add_define,ERRATA_N2_2138956)) +# Process ERRATA_N2_2138953 flag +$(eval $(call assert_boolean,ERRATA_N2_2138953)) +$(eval $(call add_define,ERRATA_N2_2138953)) + # Process ERRATA_A710_2055002 flag $(eval $(call assert_boolean,ERRATA_A710_2055002)) $(eval $(call add_define,ERRATA_A710_2055002)) -- cgit v1.2.3 From 8e140272fbd4ea00d1a9d86dced18ce6eb3a9981 Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Tue, 28 Sep 2021 13:41:03 -0700 Subject: errata: workaround for Neoverse-V1 erratum 2108267 Neoverse-V1 erratum 2108267 is a Cat B erratum that applies to revisions r0p0, r1p0, and r1p1 of CPU. It is still open. The workaround is to write the value 2'b11 to the PF_MODE bits in the CPUECTLR_EL1 register which will place the data prefetcher in the most conservative mode instead of disabling it. SDEN can be found here: https://developer.arm.com/documentation/SDEN1401781/latest Signed-off-by: nayanpatel-arm Change-Id: Iedcb84a7ad34af7083116818f49d7296f7d9bf94 --- docs/design/cpu-specific-build-macros.rst | 4 ++++ include/lib/cpus/aarch64/neoverse_v1.h | 3 +++ lib/cpus/aarch64/neoverse_v1.S | 35 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 12 +++++++++-- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 9676ae787..944228ce1 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -371,6 +371,10 @@ For Neoverse V1, the following errata build flags are defined : CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. It is still open. +- ``ERRATA_V1_2108267``: This applies errata 2108267 workaround to Neoverse-V1 + CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. + It is still open. + For Cortex-A710, the following errata build flags are defined : - ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to diff --git a/include/lib/cpus/aarch64/neoverse_v1.h b/include/lib/cpus/aarch64/neoverse_v1.h index cfb26ab61..e43c90798 100644 --- a/include/lib/cpus/aarch64/neoverse_v1.h +++ b/include/lib/cpus/aarch64/neoverse_v1.h @@ -15,6 +15,9 @@ #define NEOVERSE_V1_CPUECTLR_EL1 S3_0_C15_C1_4 #define NEOVERSE_V1_CPUECTLR_EL1_BIT_8 (ULL(1) << 8) #define NEOVERSE_V1_CPUECTLR_EL1_BIT_53 (ULL(1) << 53) +#define NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV ULL(3) +#define CPUECTLR_EL1_PF_MODE_LSB U(6) +#define CPUECTLR_EL1_PF_MODE_WIDTH U(2) /******************************************************************************* * CPU Power Control register specific definitions diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S index 0bcf52a78..200f67de3 100644 --- a/lib/cpus/aarch64/neoverse_v1.S +++ b/lib/cpus/aarch64/neoverse_v1.S @@ -259,6 +259,35 @@ func check_errata_2139242 b cpu_rev_var_ls endfunc check_errata_2139242 + /* -------------------------------------------------- + * Errata Workaround for Neoverse V1 Errata #2108267. + * This applies to revisions r0p0, r1p0, and r1p1, it + * is still open. + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_neoverse_v1_2108267_wa + /* Check workaround compatibility. */ + mov x17, x30 + bl check_errata_2108267 + cbz x0, 1f + + /* Apply the workaround. */ + mrs x1, NEOVERSE_V1_CPUECTLR_EL1 + mov x0, #NEOVERSE_V1_CPUECTLR_EL1_PF_MODE_CNSRV + bfi x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH + msr NEOVERSE_V1_CPUECTLR_EL1, x1 +1: + ret x17 +endfunc errata_neoverse_v1_2108267_wa + +func check_errata_2108267 + /* Applies to r0p0, r1p0, r1p1 */ + mov x1, #0x11 + b cpu_rev_var_ls +endfunc check_errata_2108267 + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- @@ -296,6 +325,7 @@ func neoverse_v1_errata_report report_errata ERRATA_V1_1940577, neoverse_v1, 1940577 report_errata ERRATA_V1_1966096, neoverse_v1, 1966096 report_errata ERRATA_V1_2139242, neoverse_v1, 2139242 + report_errata ERRATA_V1_2108267, neoverse_v1, 2108267 ldp x8, x30, [sp], #16 ret @@ -344,6 +374,11 @@ func neoverse_v1_reset_func bl errata_neoverse_v1_2139242_wa #endif +#if ERRATA_V1_2108267 + mov x0, x18 + bl errata_neoverse_v1_2108267_wa +#endif + ret x19 endfunc neoverse_v1_reset_func diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 1d470e20b..9b2d5464d 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -411,11 +411,15 @@ ERRATA_V1_1940577 ?=0 # Flag to apply erratum 1966096 workaround during reset. This erratum applies # to revisions r1p0 and r1p1 of the Neoverse V1 CPU and is open. This issue # exists in r0p0 as well but there is no workaround for that revision. -ERRATA_V1_1966096 ?=0 +ERRATA_V1_1966096 ?=0 # Flag to apply erratum 2139242 workaround during reset. This erratum applies # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open. -ERRATA_V1_2139242 ?=0 +ERRATA_V1_2139242 ?=0 + +# Flag to apply erratum 2108267 workaround during reset. This erratum applies +# to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open. +ERRATA_V1_2108267 ?=0 # Flag to apply erratum 1987031 workaround during reset. This erratum applies # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open. @@ -802,6 +806,10 @@ $(eval $(call add_define,ERRATA_V1_1966096)) $(eval $(call assert_boolean,ERRATA_V1_2139242)) $(eval $(call add_define,ERRATA_V1_2139242)) +# Process ERRATA_V1_2108267 flag +$(eval $(call assert_boolean,ERRATA_V1_2108267)) +$(eval $(call add_define,ERRATA_V1_2108267)) + # Process ERRATA_A710_1987031 flag $(eval $(call assert_boolean,ERRATA_A710_1987031)) $(eval $(call add_define,ERRATA_A710_1987031)) -- cgit v1.2.3 From b36fe21243d2113cb3dbd746a3698cd112948fa3 Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Tue, 28 Sep 2021 17:31:50 -0700 Subject: errata: workaround for Cortex-A78 erratum 2132060 Cortex-A78 erratum 2132060 is a Cat B erratum that applies to revisions r0p0, r1p0, r1p1, and r1p2 of CPU. It is still open. The workaround is to write the value 2'b11 to the PF_MODE bits in the CPUECTLR_EL1 register which will place the data prefetcher in the most conservative mode instead of disabling it. SDEN can be found here: https://developer.arm.com/documentation/SDEN1401784/latest Signed-off-by: nayanpatel-arm Change-Id: If7dec72578633d37d110d103099e406c3a970ff7 --- docs/design/cpu-specific-build-macros.rst | 4 ++++ include/lib/cpus/aarch64/cortex_a78.h | 3 +++ lib/cpus/aarch64/cortex_a78.S | 35 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 +++++++ 4 files changed, 50 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 944228ce1..3955a0530 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -284,6 +284,10 @@ For Cortex-A78, the following errata build flags are defined : - ``ERRATA_A78_1952683``: This applies errata 1952683 workaround to Cortex-A78 CPU. This needs to be enabled for revision r0p0, it is fixed in r1p0. +- ``ERRATA_A78_2132060``: This applies errata 2132060 workaround to Cortex-A78 + CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It + is still open. + For Cortex-A78 AE, the following errata build flags are defined : - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78 diff --git a/include/lib/cpus/aarch64/cortex_a78.h b/include/lib/cpus/aarch64/cortex_a78.h index 4bc49f303..42b08336d 100644 --- a/include/lib/cpus/aarch64/cortex_a78.h +++ b/include/lib/cpus/aarch64/cortex_a78.h @@ -16,6 +16,9 @@ ******************************************************************************/ #define CORTEX_A78_CPUECTLR_EL1 S3_0_C15_C1_4 #define CORTEX_A78_CPUECTLR_EL1_BIT_8 (ULL(1) << 8) +#define CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV ULL(3) +#define CPUECTLR_EL1_PF_MODE_LSB U(6) +#define CPUECTLR_EL1_PF_MODE_WIDTH U(2) /******************************************************************************* * CPU Power Control register specific definitions diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index 3a74571f0..4e8a228ed 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -198,6 +198,35 @@ func check_errata_1952683 b cpu_rev_var_ls endfunc check_errata_1952683 +/* -------------------------------------------------- + * Errata Workaround for Cortex A78 Errata 2132060. + * This applies to revisions r0p0, r1p0, r1p1, and r1p2. + * It is still open. + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_a78_2132060_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2132060 + cbz x0, 1f + + /* Apply the workaround. */ + mrs x1, CORTEX_A78_CPUECTLR_EL1 + mov x0, #CORTEX_A78_CPUECTLR_EL1_PF_MODE_CNSRV + bfi x1, x0, #CPUECTLR_EL1_PF_MODE_LSB, #CPUECTLR_EL1_PF_MODE_WIDTH + msr CORTEX_A78_CPUECTLR_EL1, x1 +1: + ret x17 +endfunc errata_a78_2132060_wa + +func check_errata_2132060 + /* Applies to r0p0, r0p1, r1p1, and r1p2 */ + mov x1, #0x12 + b cpu_rev_var_ls +endfunc check_errata_2132060 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- @@ -232,6 +261,11 @@ func cortex_a78_reset_func bl errata_a78_1952683_wa #endif +#if ERRATA_A78_2132060 + mov x0, x18 + bl errata_a78_2132060_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -291,6 +325,7 @@ func cortex_a78_errata_report report_errata ERRATA_A78_1951500, cortex_a78, 1951500 report_errata ERRATA_A78_1821534, cortex_a78, 1821534 report_errata ERRATA_A78_1952683, cortex_a78, 1952683 + report_errata ERRATA_A78_2132060, cortex_a78, 2132060 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 9b2d5464d..94ba43091 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -327,6 +327,10 @@ ERRATA_A78_1821534 ?=0 # to revision r0p0 of the A78 cpu and was fixed in the revision r1p0. ERRATA_A78_1952683 ?=0 +# Flag to apply erratum 2132060 workaround during reset. This erratum applies +# to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open. +ERRATA_A78_2132060 ?=0 + # Flag to apply T32 CLREX workaround during reset. This erratum applies # only to r0p0 and r1p0 of the Neoverse N1 cpu. ERRATA_N1_1043202 ?=0 @@ -718,6 +722,10 @@ $(eval $(call add_define,ERRATA_A78_1821534)) $(eval $(call assert_boolean,ERRATA_A78_1952683)) $(eval $(call add_define,ERRATA_A78_1952683)) +# Process ERRATA_A78_2132060 flag +$(eval $(call assert_boolean,ERRATA_A78_2132060)) +$(eval $(call add_define,ERRATA_A78_2132060)) + # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) -- cgit v1.2.3 From 81c272b3b71af38bc5cfb10bbe5722e328a1578e Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 8 Jul 2021 16:51:14 -0500 Subject: feat(rme): add register definitions and helper functions for FEAT_RME This patch adds new register and bit definitions for the Armv9-A Realm Management Extension (RME) as described in the Arm document DDI0615 (https://developer.arm.com/documentation/ddi0615/latest). The patch also adds TLB maintenance functions and a function to detect the presence of RME feature. Signed-off-by: Zelalem Aweke Change-Id: I03d2af7ea41a20a9e8a362a36b8099e3b4d18a11 --- include/arch/aarch64/arch.h | 92 ++++++++++++++++++++++++++++++++++++ include/arch/aarch64/arch_features.h | 11 +++++ include/arch/aarch64/arch_helpers.h | 29 +++++++++++- lib/aarch64/misc_helpers.S | 18 +++++++ 4 files changed, 148 insertions(+), 2 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 1b3ae0221..1053006a9 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -182,6 +182,11 @@ #define ID_AA64PFR0_CSV2_SHIFT U(56) #define ID_AA64PFR0_CSV2_MASK ULL(0xf) #define ID_AA64PFR0_CSV2_LENGTH U(4) +#define ID_AA64PFR0_FEAT_RME_SHIFT U(52) +#define ID_AA64PFR0_FEAT_RME_MASK ULL(0xf) +#define ID_AA64PFR0_FEAT_RME_LENGTH U(4) +#define ID_AA64PFR0_FEAT_RME_NOT_SUPPORTED U(0) +#define ID_AA64PFR0_FEAT_RME_V1 U(1) /* Exception level handling */ #define EL_IMPL_NONE ULL(0) @@ -432,6 +437,9 @@ /* SCR definitions */ #define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5)) +#define SCR_NSE_SHIFT U(62) +#define SCR_NSE_BIT (ULL(1) << SCR_NSE_SHIFT) +#define SCR_GPF_BIT (UL(1) << 48) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) #define SCR_HXEn_BIT (UL(1) << 38) @@ -1092,6 +1100,90 @@ #define AMEVCNTVOFF1E_EL2 S3_4_C13_C11_6 #define AMEVCNTVOFF1F_EL2 S3_4_C13_C11_7 +/******************************************************************************* + * Realm management extension register definitions + ******************************************************************************/ + +/* GPCCR_EL3 definitions */ +#define GPCCR_EL3 S3_6_C2_C1_6 + +/* Least significant address bits protected by each entry in level 0 GPT */ +#define GPCCR_L0GPTSZ_SHIFT U(20) +#define GPCCR_L0GPTSZ_MASK U(0xF) +#define GPCCR_L0GPTSZ_30BITS U(0x0) +#define GPCCR_L0GPTSZ_34BITS U(0x4) +#define GPCCR_L0GPTSZ_36BITS U(0x6) +#define GPCCR_L0GPTSZ_39BITS U(0x9) +#define SET_GPCCR_L0GPTSZ(x) \ + ((x & GPCCR_L0GPTSZ_MASK) << GPCCR_L0GPTSZ_SHIFT) + +/* Granule protection check priority bit definitions */ +#define GPCCR_GPCP_SHIFT U(17) +#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) + +/* Granule protection check bit definitions */ +#define GPCCR_GPC_SHIFT U(16) +#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) + +/* Physical granule size bit definitions */ +#define GPCCR_PGS_SHIFT U(14) +#define GPCCR_PGS_MASK U(0x3) +#define GPCCR_PGS_4K U(0x0) +#define GPCCR_PGS_16K U(0x2) +#define GPCCR_PGS_64K U(0x1) +#define SET_GPCCR_PGS(x) \ + ((x & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) + +/* GPT fetch shareability attribute bit definitions */ +#define GPCCR_SH_SHIFT U(12) +#define GPCCR_SH_MASK U(0x3) +#define GPCCR_SH_NS U(0x0) +#define GPCCR_SH_OS U(0x2) +#define GPCCR_SH_IS U(0x3) +#define SET_GPCCR_SH(x) \ + ((x & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) + +/* GPT fetch outer cacheability attribute bit definitions */ +#define GPCCR_ORGN_SHIFT U(10) +#define GPCCR_ORGN_MASK U(0x3) +#define GPCCR_ORGN_NC U(0x0) +#define GPCCR_ORGN_WB_RA_WA U(0x1) +#define GPCCR_ORGN_WT_RA_NWA U(0x2) +#define GPCCR_ORGN_WB_RA_NWA U(0x3) +#define SET_GPCCR_ORGN(x) \ + ((x & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) + +/* GPT fetch inner cacheability attribute bit definitions */ +#define GPCCR_IRGN_SHIFT U(8) +#define GPCCR_IRGN_MASK U(0x3) +#define GPCCR_IRGN_NC U(0x0) +#define GPCCR_IRGN_WB_RA_WA U(0x1) +#define GPCCR_IRGN_WT_RA_NWA U(0x2) +#define GPCCR_IRGN_WB_RA_NWA U(0x3) +#define SET_GPCCR_IRGN(x) \ + ((x & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) + +/* Protected physical address size bit definitions */ +#define GPCCR_PPS_SHIFT U(0) +#define GPCCR_PPS_MASK U(0x7) +#define GPCCR_PPS_4GB U(0x0) +#define GPCCR_PPS_64GB U(0x1) +#define GPCCR_PPS_1TB U(0x2) +#define GPCCR_PPS_4TB U(0x3) +#define GPCCR_PPS_16TB U(0x4) +#define GPCCR_PPS_256TB U(0x5) +#define GPCCR_PPS_4PB U(0x6) +#define SET_GPCCR_PPS(x) \ + ((x & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) + +/* GPTBR_EL3 definitions */ +#define GPTBR_EL3 S3_6_C2_C1_4 + +/* Base Address for the GPT bit definitions */ +#define GPTBR_BADDR_SHIFT U(0) +#define GPTBR_BADDR_VAL_SHIFT U(12) +#define GPTBR_BADDR_MASK ULL(0xffffffffff) + /******************************************************************************* * RAS system registers ******************************************************************************/ diff --git a/include/arch/aarch64/arch_features.h b/include/arch/aarch64/arch_features.h index 3ff67e571..46cd1c982 100644 --- a/include/arch/aarch64/arch_features.h +++ b/include/arch/aarch64/arch_features.h @@ -123,4 +123,15 @@ static inline bool is_feat_hcx_present(void) ID_AA64MMFR1_EL1_HCX_MASK) == ID_AA64MMFR1_EL1_HCX_SUPPORTED); } +static inline unsigned int get_armv9_2_feat_rme_support(void) +{ + /* + * Return the RME version, zero if not supported. This function can be + * used as both an integer value for the RME version or compared to zero + * to detect RME presence. + */ + return (unsigned int)(read_id_aa64pfr0_el1() >> + ID_AA64PFR0_FEAT_RME_SHIFT) & ID_AA64PFR0_FEAT_RME_MASK; +} + #endif /* ARCH_FEATURES_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 72b87c8b9..1aadf0b8d 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -540,6 +540,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) +/* Armv9.2 RME Registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3) +DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3) + #define IS_IN_EL(x) \ (GET_EL(read_CurrentEl()) == MODE_EL##x) @@ -583,7 +587,28 @@ static inline uint64_t el_implemented(unsigned int el) } } -/* Previously defined accesor functions with incomplete register names */ +/* + * TLBIPAALLOS instruction + * (TLB Inivalidate GPT Information by PA, + * All Entries, Outer Shareable) + */ +static inline void tlbipaallos(void) +{ + __asm__("SYS #6,c8,c1,#4"); +} + +/* + * Invalidate cached copies of GPT entries + * from TLBs by physical address + * + * @pa: the starting address for the range + * of invalidation + * @size: size of the range of invalidation + */ +void gpt_tlbi_by_pa(uint64_t pa, size_t size); + + +/* Previously defined accessor functions with incomplete register names */ #define read_current_el() read_CurrentEl() diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index b6f6c9d88..cc5c5759d 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.S @@ -15,6 +15,7 @@ .globl zero_normalmem .globl zeromem .globl memcpy16 + .globl gpt_tlbi_by_pa .globl disable_mmu_el1 .globl disable_mmu_el3 @@ -592,3 +593,20 @@ func fixup_gdt_reloc b.lo 1b ret endfunc fixup_gdt_reloc + +/* + * TODO: Currently only supports size of 4KB, + * support other sizes as well. + */ +func gpt_tlbi_by_pa +#if ENABLE_ASSERTIONS + cmp x1, #PAGE_SIZE_4KB + ASM_ASSERT(eq) + tst x0, #(PAGE_SIZE_MASK) + ASM_ASSERT(eq) +#endif + lsr x0, x0, #FOUR_KB_SHIFT /* 4KB size encoding is zero */ + sys #6, c8, c4, #3, x0 /* TLBI RPAOS, */ + dsb sy + ret +endfunc gpt_tlbi_by_pa -- cgit v1.2.3 From 4693ff7225faadc5ad1bcd1c2fb3fbbb8fe1aed0 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 8 Jul 2021 17:13:09 -0500 Subject: feat(rme): add Realm security state definition FEAT_RME introduces two additional security states, Root and Realm security states. This patch adds Realm security state awareness to SMCCC helpers and entry point info structure. Signed-off-by: Zelalem Aweke Change-Id: I9cdefcc1aa71259b2de46e5fb62b28d658fa59bd --- bl31/aarch64/runtime_exceptions.S | 15 +++++++++++++++ include/common/ep_info.h | 11 +++++++++-- include/export/common/ep_info_exp.h | 18 +++++++++++++++--- include/lib/smccc.h | 27 ++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 6 deletions(-) diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index 51eb2bd47..0d0a12d3e 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.S @@ -500,6 +500,21 @@ smc_handler64: stp x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] str x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] + /* Clear flag register */ + mov x7, xzr + +#if ENABLE_RME + /* Copy SCR_EL3.NSE bit to the flag to indicate caller's security */ + ubfx x7, x18, #SCR_NSE_SHIFT, 1 + + /* + * Shift copied SCR_EL3.NSE bit by 5 to create space for + * SCR_EL3.NS bit. Bit 5 of the flag correspondes to + * the SCR_EL3.NSE bit. + */ + lsl x7, x7, #5 +#endif /* ENABLE_RME */ + /* Copy SCR_EL3.NS bit to the flag to indicate caller's security */ bfi x7, x18, #0, #1 diff --git a/include/common/ep_info.h b/include/common/ep_info.h index 4bfa1fa6a..771572ce9 100644 --- a/include/common/ep_info.h +++ b/include/common/ep_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,14 +18,21 @@ #define SECURE EP_SECURE #define NON_SECURE EP_NON_SECURE +#define REALM EP_REALM +#if ENABLE_RME +#define sec_state_is_valid(s) (((s) == SECURE) || \ + ((s) == NON_SECURE) || \ + ((s) == REALM)) +#else #define sec_state_is_valid(s) (((s) == SECURE) || ((s) == NON_SECURE)) +#endif #define PARAM_EP_SECURITY_MASK EP_SECURITY_MASK #define NON_EXECUTABLE EP_NON_EXECUTABLE #define EXECUTABLE EP_EXECUTABLE -/* Secure or Non-secure image */ +/* Get/set security state of an image */ #define GET_SECURITY_STATE(x) ((x) & EP_SECURITY_MASK) #define SET_SECURITY_STATE(x, security) \ ((x) = ((x) & ~EP_SECURITY_MASK) | (security)) diff --git a/include/export/common/ep_info_exp.h b/include/export/common/ep_info_exp.h index 9d2969f3f..a5bd10ac8 100644 --- a/include/export/common/ep_info_exp.h +++ b/include/export/common/ep_info_exp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,11 +24,23 @@ #define ENTRY_POINT_INFO_ARGS_OFFSET U(0x14) #endif -/* Security state of the image. */ -#define EP_SECURITY_MASK UL(0x1) +/* + * Security state of the image. Bit 0 and + * bit 5 are used to determine the security + * state of the image as follows: + * + * --------------------------------- + * Bit 5 | Bit 0 | Security state + * --------------------------------- + * 0 0 EP_SECURE + * 0 1 EP_NON_SECURE + * 1 1 EP_REALM + */ +#define EP_SECURITY_MASK UL(0x21) #define EP_SECURITY_SHIFT UL(0) #define EP_SECURE UL(0x0) #define EP_NON_SECURE UL(0x1) +#define EP_REALM UL(0x21) /* Endianness of the image. */ #define EP_EE_MASK U(0x2) diff --git a/include/lib/smccc.h b/include/lib/smccc.h index deaeb1d1d..1a39f24c7 100644 --- a/include/lib/smccc.h +++ b/include/lib/smccc.h @@ -108,9 +108,24 @@ #define SMC_ARCH_CALL_NOT_REQUIRED -2 #define SMC_ARCH_CALL_INVAL_PARAM -3 -/* Various flags passed to SMC handlers */ +/* + * Various flags passed to SMC handlers + * + * Bit 5 and bit 0 of the flag are used to + * determine the source security state as + * follows: + * --------------------------------- + * Bit 5 | Bit 0 | Security state + * --------------------------------- + * 0 0 SMC_FROM_SECURE + * 0 1 SMC_FROM_NON_SECURE + * 1 1 SMC_FROM_REALM + */ + #define SMC_FROM_SECURE (U(0) << 0) #define SMC_FROM_NON_SECURE (U(1) << 0) +#define SMC_FROM_REALM U(0x21) +#define SMC_FROM_MASK U(0x21) #ifndef __ASSEMBLER__ @@ -118,8 +133,18 @@ #include +#if ENABLE_RME +#define is_caller_non_secure(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_NON_SECURE) +#define is_caller_secure(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_SECURE) +#define is_caller_realm(_f) (((_f) & SMC_FROM_MASK) \ + == SMC_FROM_REALM) +#define caller_sec_state(_f) ((_f) & SMC_FROM_MASK) +#else /* ENABLE_RME */ #define is_caller_non_secure(_f) (((_f) & SMC_FROM_NON_SECURE) != U(0)) #define is_caller_secure(_f) (!is_caller_non_secure(_f)) +#endif /* ENABLE_RME */ /* The macro below is used to identify a Standard Service SMC call */ #define is_std_svc_call(_fid) (GET_SMC_OEN(_fid) == OEN_STD_START) -- cgit v1.2.3 From 83ad3819bf3632d903c544225d221b8e9849fc8e Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Thu, 5 Aug 2021 22:27:03 +0100 Subject: refactor(measured boot): remove unused extern Change-Id: I4fb7a79c2f31973a3cd181feaface9a42bc3246f Signed-off-by: Manish V Badarkhe --- include/drivers/measured_boot/measured_boot.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/drivers/measured_boot/measured_boot.h b/include/drivers/measured_boot/measured_boot.h index f8769ab43..05be4a941 100644 --- a/include/drivers/measured_boot/measured_boot.h +++ b/include/drivers/measured_boot/measured_boot.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,9 +11,6 @@ #include -/* Platform specific table of image IDs, names and PCRs */ -extern const image_data_t images_data[]; - /* Functions' declarations */ void measured_boot_init(void); void measured_boot_finish(void); -- cgit v1.2.3 From 74d720a026735263d2f290fd05370dad0d4c7219 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 26 Aug 2021 15:39:37 +0200 Subject: fix(xlat): remove always true check in assert This issue was found with Clang compiler: lib/xlat_tables_v2/aarch32/xlat_tables_arch.c:206:34: error: result of comparison of constant 4294967296 with expression of type 'uintptr_t' (aka 'unsigned long') is always true [-Werror,-Wtautological-constant-out-of-range-compare] assert(virtual_addr_space_size <= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ On AARCH32, MAX_VIRT_ADDR_SPACE_SIZE is defined as 1 << 32, and a 32 bit uintptr_t is always lower. Just remove the assert line. Change-Id: Iec2c05290cede6e9fedbbf7b7dff2118bd1f9b16 Signed-off-by: Yann Gautier --- lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index b69c6702b..a95ef072d 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -203,8 +203,6 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, assert(virtual_addr_space_size >= xlat_get_min_virt_addr_space_size()); - assert(virtual_addr_space_size <= - MAX_VIRT_ADDR_SPACE_SIZE); assert(IS_POWER_OF_TWO(virtual_addr_space_size)); /* -- cgit v1.2.3 From de9fdb9b5925ae08137d4212a85e9a1d319509c9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 14 May 2021 16:13:28 +0100 Subject: feat(arm_fpga): add kernel trampoline The arm64 Linux kernel needed to be loaded at a certain offset within any 2MB aligned region; this value was configured at compile time and stored in the Linux kernel image header. The default value was always 512KiB, so this is the value we use in the TF-A build system for the kernel load address. However the whole scheme around the TEXT_OFFSET changed in Linux v5.8: Linux kernels became fully relocatable, so this value is largely ignored now, and its default value changed to 0. The only remainder is a warning message at boot time in case there is a mismatch: [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader! To avoid this warning, and to make TF-A Linux kernel boot protocol compliant, we should load newer kernels to offset 0 of a 2 MB region. This can be done by the user at FPGA boot time, but BL31 needs to know about this address. As we can't change the build default to 0 without breaking older kernels, we should try to make a build dealing with both versions: This patch introduces a small trampoline code, which gets loaded at 512KB of DRAM, and branches up to 2MB. If users load their newer kernels at 2MB, this trampoline will cover them. In case an older kernel is loaded at 512KB, it will overwrite this trampoline code, so it would still work. Change-Id: If49ca86f5dca380036caf2555349748722901277 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/build_axf.ld.S | 6 +++++ plat/arm/board/arm_fpga/kernel_trampoline.S | 35 +++++++++++++++++++++++++++++ plat/arm/board/arm_fpga/platform.mk | 3 ++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 plat/arm/board/arm_fpga/kernel_trampoline.S diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S index d7cd00882..60b0abff6 100644 --- a/plat/arm/board/arm_fpga/build_axf.ld.S +++ b/plat/arm/board/arm_fpga/build_axf.ld.S @@ -17,6 +17,7 @@ OUTPUT_ARCH(aarch64) INPUT(./bl31/bl31.elf) INPUT(./rom_trampoline.o) +INPUT(./kernel_trampoline.o) TARGET(binary) INPUT(./fdts/arm_fpga.dtb) @@ -41,6 +42,11 @@ SECTIONS *arm_fpga.dtb } + .kern_tramp (PRELOADED_BL33_BASE): { + *kernel_trampoline.o(.text*) + KEEP(*(.kern_tramp)) + } + /DISCARD/ : { *(.debug_*) } /DISCARD/ : { *(.note*) } /DISCARD/ : { *(.comment*) } diff --git a/plat/arm/board/arm_fpga/kernel_trampoline.S b/plat/arm/board/arm_fpga/kernel_trampoline.S new file mode 100644 index 000000000..f4c08ef28 --- /dev/null +++ b/plat/arm/board/arm_fpga/kernel_trampoline.S @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * The traditional arm64 Linux kernel load address is 512KiB from the + * beginning of DRAM, caused by this having been the default value of the + * kernel's CONFIG_TEXT_OFFSET Kconfig value. + * However kernel version 5.8 changed the default offset (into a 2MB page) + * to 0, so TF-A's default assumption is no longer true. Fortunately the + * kernel got more relaxed about this offset at the same time, so it + * tolerates the wrong offset, but issues a warning: + * [Firmware Bug]: Kernel image misaligned at boot, please fix your bootloader! + * + * We cannot easily change the load address offset in TF-A to be 2MiB, because + * this would break older kernels - and they are not as forgiving in this + * respect. + * + * But we can allow users to load the kernel at the right offset, and + * offer this trampoline here to transition to this new load address. + * Any older kernels, or newer kernels misloaded, will overwrite this code + * here, so it does no harm in this case. + */ + +#include +#include + +.text +.global _tramp_start + +_tramp_start: + adr x4, _tramp_start + orr x4, x4, #0x1fffff + add x4, x4, #1 /* align up to 2MB */ + br x4 diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index baffbcf62..3183965b2 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -118,9 +118,10 @@ BL31_SOURCES += common/fdt_wrappers.c \ ${FPGA_GIC_SOURCES} $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31)) +$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,31)) $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31)) -bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/build_axf.ld +bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld $(ECHO) " LD $@" $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf -- cgit v1.2.3 From 9177e4fd9356b0f249be8b6fe14f222e10f1e6cd Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 20 Aug 2021 16:23:23 +0100 Subject: fix(arm_fpga): streamline generated axf file For convenience we let the build system generate an ELF file (named bl31.axf), containing all the trampolines, BL31 code and the DTB in one file. This can be fed directly into the FPGA payload tool, and it will load the bits at the right addresses. Since this ELF file is more used as a "container with load addresses", there is no need for normal ELF features like alignment or a symbol table. Remove unnecessary sections from that output file, by doing a static "link", dropping the NOBITS stacks section, and by adding "-n" to the linker command line (to avoid page alignment). This trims the generated .axf file, and makes it smaller. Change-Id: I5768543101d667fb4a3b70e60b08cfe970d2a2b6 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/build_axf.ld.S | 2 +- plat/arm/board/arm_fpga/platform.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S index 60b0abff6..b4bc7d884 100644 --- a/plat/arm/board/arm_fpga/build_axf.ld.S +++ b/plat/arm/board/arm_fpga/build_axf.ld.S @@ -34,7 +34,6 @@ SECTIONS .bl31 (BL31_BASE): { ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned"); *bl31.elf(.text* .data* .rodata* ro* .bss*) - *bl31.elf(.stack) } .dtb (FPGA_PRELOADED_DTB_BASE): { @@ -47,6 +46,7 @@ SECTIONS KEEP(*(.kern_tramp)) } + /DISCARD/ : { *(stacks) } /DISCARD/ : { *(.debug_*) } /DISCARD/ : { *(.note*) } /DISCARD/ : { *(.comment*) } diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 3183965b2..1217425f0 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -123,6 +123,6 @@ $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_a bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld $(ECHO) " LD $@" - $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -o ${BUILD_PLAT}/bl31.axf + $(Q)$(LD) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -s -n -o ${BUILD_PLAT}/bl31.axf all: bl31.axf -- cgit v1.2.3 From 362182386bafbda9e6671be921fa30cc20610d30 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 8 Jul 2021 17:23:04 -0500 Subject: feat(rme): add xlat table library changes for FEAT_RME FEAT_RME adds a new bit (NSE) in the translation table descriptor to determine the Physical Address Space (PAS) of an EL3 stage 1 translation according to the following mapping: TTD.NSE TTD.NS | PAS ================================= 0 0 | Secure 0 1 | Non-secure 1 0 | Root 1 1 | Realm This patch adds modifications to version 2 of the translation table library accordingly. Bits 4 and 5 in mmap attribute are used to determine the PAS. Signed-off-by: Zelalem Aweke Change-Id: I82790f6900b7a1ab9494c732eac7b9808a388103 --- include/lib/xlat_tables/xlat_tables.h | 9 +++++++- include/lib/xlat_tables/xlat_tables_defs.h | 3 ++- include/lib/xlat_tables/xlat_tables_v2.h | 30 ++++++++++++++++++++------- lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 17 +++++++++++++++ lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 29 +++++++++++++++++++++++++- lib/xlat_tables_v2/xlat_tables_core.c | 11 ++++++---- lib/xlat_tables_v2/xlat_tables_private.h | 5 ++++- lib/xlat_tables_v2/xlat_tables_utils.c | 18 +++++++++++++++- 8 files changed, 105 insertions(+), 17 deletions(-) diff --git a/include/lib/xlat_tables/xlat_tables.h b/include/lib/xlat_tables/xlat_tables.h index 082bb5e45..a15696976 100644 --- a/include/lib/xlat_tables/xlat_tables.h +++ b/include/lib/xlat_tables/xlat_tables.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -72,6 +72,13 @@ #define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) #define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) +/* Memory type for EL3 regions */ +#if ENABLE_RME +#error FEAT_RME requires version 2 of the Translation Tables Library +#else +#define EL3_PAS MT_SECURE +#endif + /* * Structure for specifying a single region of memory. */ diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h index 579d8d89c..2d0949b51 100644 --- a/include/lib/xlat_tables/xlat_tables_defs.h +++ b/include/lib/xlat_tables/xlat_tables_defs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -142,6 +142,7 @@ #define AP_NO_ACCESS_UNPRIVILEGED (AP1_NO_ACCESS_UNPRIVILEGED << 4) #define AP_ONE_VA_RANGE_RES1 (AP1_RES1 << 4) #define NS (U(0x1) << 3) +#define EL3_S1_NSE (U(0x1) << 9) #define ATTR_NON_CACHEABLE_INDEX ULL(0x2) #define ATTR_DEVICE_INDEX ULL(0x1) #define ATTR_IWBWA_OWBWA_NTR_INDEX ULL(0x0) diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h index 359b9839a..69ad02764 100644 --- a/include/lib/xlat_tables/xlat_tables_v2.h +++ b/include/lib/xlat_tables/xlat_tables_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -60,17 +60,22 @@ #define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK) /* Access permissions (RO/RW) */ #define MT_PERM_SHIFT U(3) -/* Security state (SECURE/NS) */ -#define MT_SEC_SHIFT U(4) + +/* Physical address space (SECURE/NS/Root/Realm) */ +#define MT_PAS_SHIFT U(4) +#define MT_PAS_MASK (U(3) << MT_PAS_SHIFT) +#define MT_PAS(_attr) ((_attr) & MT_PAS_MASK) + /* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ -#define MT_EXECUTE_SHIFT U(5) +#define MT_EXECUTE_SHIFT U(6) /* In the EL1&0 translation regime, User (EL0) or Privileged (EL1). */ -#define MT_USER_SHIFT U(6) +#define MT_USER_SHIFT U(7) /* Shareability attribute for the memory region */ -#define MT_SHAREABILITY_SHIFT U(7) +#define MT_SHAREABILITY_SHIFT U(8) #define MT_SHAREABILITY_MASK (U(3) << MT_SHAREABILITY_SHIFT) #define MT_SHAREABILITY(_attr) ((_attr) & MT_SHAREABILITY_MASK) + /* All other bits are reserved */ /* @@ -91,8 +96,10 @@ #define MT_RO (U(0) << MT_PERM_SHIFT) #define MT_RW (U(1) << MT_PERM_SHIFT) -#define MT_SECURE (U(0) << MT_SEC_SHIFT) -#define MT_NS (U(1) << MT_SEC_SHIFT) +#define MT_SECURE (U(0) << MT_PAS_SHIFT) +#define MT_NS (U(1) << MT_PAS_SHIFT) +#define MT_ROOT (U(2) << MT_PAS_SHIFT) +#define MT_REALM (U(3) << MT_PAS_SHIFT) /* * Access permissions for instruction execution are only relevant for normal @@ -149,6 +156,13 @@ typedef struct mmap_region { #define EL3_REGIME 3 #define EL_REGIME_INVALID -1 +/* Memory type for EL3 regions. With RME, EL3 is in ROOT PAS */ +#if ENABLE_RME +#define EL3_PAS MT_ROOT +#else +#define EL3_PAS MT_SECURE +#endif /* ENABLE_RME */ + /* * Declare the translation context type. * Its definition is private. diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index b69c6702b..ed6383751 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -39,6 +39,23 @@ size_t xlat_arch_get_max_supported_granule_size(void) return PAGE_SIZE_4KB; } +/* + * Determine the physical address space encoded in the 'attr' parameter. + * + * The physical address will fall into one of two spaces; secure or + * nonsecure. + */ +uint32_t xlat_arch_get_pas(uint32_t attr) +{ + uint32_t pas = MT_PAS(attr); + + if (pas == MT_NS) { + return LOWER_ATTRS(NS); + } else { /* MT_SECURE */ + return 0U; + } +} + #if ENABLE_ASSERTIONS unsigned long long xlat_arch_get_max_supported_pa(void) { diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index 3832b0703..719110a0e 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -53,6 +53,33 @@ size_t xlat_arch_get_max_supported_granule_size(void) } } +/* + * Determine the physical address space encoded in the 'attr' parameter. + * + * The physical address will fall into one of four spaces; secure, + * nonsecure, root, or realm if RME is enabled, or one of two spaces; + * secure and nonsecure otherwise. + */ +uint32_t xlat_arch_get_pas(uint32_t attr) +{ + uint32_t pas = MT_PAS(attr); + + switch (pas) { +#if ENABLE_RME + /* TTD.NSE = 1 and TTD.NS = 1 for Realm PAS */ + case MT_REALM: + return LOWER_ATTRS(EL3_S1_NSE | NS); + /* TTD.NSE = 1 and TTD.NS = 0 for Root PAS */ + case MT_ROOT: + return LOWER_ATTRS(EL3_S1_NSE); +#endif + case MT_NS: + return LOWER_ATTRS(NS); + default: /* MT_SECURE */ + return 0U; + } +} + unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr) { /* Physical address can't exceed 48 bits */ diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c index bb6d18459..de5718454 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -125,11 +125,14 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, * faults aren't managed. */ desc |= LOWER_ATTRS(ACCESS_FLAG); + + /* Determine the physical address space this region belongs to. */ + desc |= xlat_arch_get_pas(attr); + /* - * Deduce other fields of the descriptor based on the MT_NS and MT_RW - * memory region attributes. + * Deduce other fields of the descriptor based on the MT_RW memory + * region attributes. */ - desc |= ((attr & MT_NS) != 0U) ? LOWER_ATTRS(NS) : 0U; desc |= ((attr & MT_RW) != 0U) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); /* diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h index 863470cf3..42c9a43ea 100644 --- a/lib/xlat_tables_v2/xlat_tables_private.h +++ b/lib/xlat_tables_v2/xlat_tables_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,6 +40,9 @@ extern uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; +/* Determine the physical address space encoded in the 'attr' parameter. */ +uint32_t xlat_arch_get_pas(uint32_t attr); + /* * Return the execute-never mask that will prevent instruction fetch at the * given translation regime. diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c index 9fae7e917..df1738642 100644 --- a/lib/xlat_tables_v2/xlat_tables_utils.c +++ b/lib/xlat_tables_v2/xlat_tables_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -95,7 +95,23 @@ static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc) ? "-USER" : "-PRIV"); } +#if ENABLE_RME + switch (desc & LOWER_ATTRS(EL3_S1_NSE | NS)) { + case 0ULL: + printf("-S"); + break; + case LOWER_ATTRS(NS): + printf("-NS"); + break; + case LOWER_ATTRS(EL3_S1_NSE): + printf("-RT"); + break; + default: /* LOWER_ATTRS(EL3_S1_NSE | NS) */ + printf("-RL"); + } +#else printf(((LOWER_ATTRS(NS) & desc) != 0ULL) ? "-NS" : "-S"); +#endif #ifdef __aarch64__ /* Check Guarded Page bit */ -- cgit v1.2.3 From 6c09af9f8b36cdfa1dc4d5052f7e4792f63fa88a Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 11:37:10 -0500 Subject: feat(rme): run BL2 in root world when FEAT_RME is enabled This patch enables BL2 to run in root world (EL3) which is needed as per the security model of RME-enabled systems. Using the existing BL2_AT_EL3 TF-A build option is not convenient because that option assumes TF-A BL1 doesn't exist, which is not the case for RME-enabled systems. For the purposes of RME, we use a normal BL1 image but we also want to run BL2 in EL3 as normally as possible, therefore rather than use the special bl2_entrypoint function in bl2_el3_entrypoint.S, we use a new bl2_entrypoint function (in bl2_rme_entrypoint.S) which doesn't need reset or mailbox initialization code seen in the el3_entrypoint_common macro. The patch also cleans up bl2_el3_entrypoint.S, moving the bl2_run_next_image function to its own file to avoid duplicating code. Signed-off-by: Zelalem Aweke Change-Id: I99821b4cd550cadcb701f4c0c4dc36da81c7ef55 --- bl1/aarch64/bl1_context_mgmt.c | 38 +++++++++++++++++- bl1/aarch64/bl1_entrypoint.S | 40 ++++++++++++++++++- bl1/bl1_private.h | 5 ++- bl2/aarch32/bl2_el3_entrypoint.S | 37 +----------------- bl2/aarch32/bl2_run_next_image.S | 46 ++++++++++++++++++++++ bl2/aarch64/bl2_el3_entrypoint.S | 37 +----------------- bl2/aarch64/bl2_rme_entrypoint.S | 67 ++++++++++++++++++++++++++++++++ bl2/aarch64/bl2_run_next_image.S | 45 +++++++++++++++++++++ bl2/bl2.ld.S | 6 ++- bl2/bl2.mk | 15 ++++++- bl2/bl2_main.c | 31 +++++++-------- include/arch/aarch64/el3_common_macros.S | 14 ++++++- lib/aarch64/misc_helpers.S | 3 +- 13 files changed, 287 insertions(+), 97 deletions(-) create mode 100644 bl2/aarch32/bl2_run_next_image.S create mode 100644 bl2/aarch64/bl2_rme_entrypoint.S create mode 100644 bl2/aarch64/bl2_run_next_image.S diff --git a/bl1/aarch64/bl1_context_mgmt.c b/bl1/aarch64/bl1_context_mgmt.c index 2a8d58efd..b9a7e5ba6 100644 --- a/bl1/aarch64/bl1_context_mgmt.c +++ b/bl1/aarch64/bl1_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,7 @@ /* Following contains the cpu context pointers. */ static void *bl1_cpu_context_ptr[2]; +entry_point_info_t *bl2_ep_info; void *cm_get_context(uint32_t security_state) @@ -30,6 +31,40 @@ void cm_set_context(void *context, uint32_t security_state) bl1_cpu_context_ptr[security_state] = context; } +#if ENABLE_RME +/******************************************************************************* + * This function prepares the entry point information to run BL2 in Root world, + * i.e. EL3, for the case when FEAT_RME is enabled. + ******************************************************************************/ +void bl1_prepare_next_image(unsigned int image_id) +{ + image_desc_t *bl2_desc; + + assert(image_id == BL2_IMAGE_ID); + + /* Get the image descriptor. */ + bl2_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); + assert(bl2_desc != NULL); + + /* Get the entry point info. */ + bl2_ep_info = &bl2_desc->ep_info; + + bl2_ep_info->spsr = (uint32_t)SPSR_64(MODE_EL3, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + + /* + * Flush cache since bl2_ep_info is accessed after MMU is disabled + * before jumping to BL2. + */ + flush_dcache_range((uintptr_t)bl2_ep_info, sizeof(entry_point_info_t)); + + /* Indicate that image is in execution state. */ + bl2_desc->state = IMAGE_STATE_EXECUTED; + + /* Print debug info and flush the console before running BL2. */ + print_entry_point_info(bl2_ep_info); +} +#else /******************************************************************************* * This function prepares the context for Secure/Normal world images. * Normal world images are transitioned to EL2(if supported) else EL1. @@ -93,3 +128,4 @@ void bl1_prepare_next_image(unsigned int image_id) print_entry_point_info(next_bl_ep); } +#endif /* ENABLE_RME */ diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S index 00f27184d..f61c06023 100644 --- a/bl1/aarch64/bl1_entrypoint.S +++ b/bl1/aarch64/bl1_entrypoint.S @@ -1,13 +1,15 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include .globl bl1_entrypoint + .globl bl1_run_bl2_in_root /* ----------------------------------------------------- @@ -66,5 +68,41 @@ func bl1_entrypoint * Do the transition to next boot image. * -------------------------------------------------- */ +#if ENABLE_RME + b bl1_run_bl2_in_root +#else b el3_exit +#endif endfunc bl1_entrypoint + + /* ----------------------------------------------------- + * void bl1_run_bl2_in_root(); + * This function runs BL2 in root/EL3 when RME is enabled. + * ----------------------------------------------------- + */ + +func bl1_run_bl2_in_root + /* read bl2_ep_info */ + adrp x20, bl2_ep_info + add x20, x20, :lo12:bl2_ep_info + ldr x20, [x20] + + /* --------------------------------------------- + * MMU needs to be disabled because BL2 executes + * in EL3. It will initialize the address space + * according to its own requirements. + * --------------------------------------------- + */ + bl disable_mmu_icache_el3 + tlbi alle3 + + ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] + msr elr_el3, x0 + msr spsr_el3, x1 + + ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] + ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] + ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] + ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] + exception_return +endfunc bl1_run_bl2_in_root diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h index 2cfeeea28..e119ba727 100644 --- a/bl1/bl1_private.h +++ b/bl1/bl1_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,8 @@ #include +extern entry_point_info_t *bl2_ep_info; + /****************************************** * Function prototypes *****************************************/ @@ -18,6 +20,7 @@ void bl1_arch_setup(void); void bl1_arch_next_el_setup(void); void bl1_prepare_next_image(unsigned int image_id); +void bl1_run_bl2_in_root(void); u_register_t bl1_fwu_smc_handler(unsigned int smc_fid, u_register_t x1, diff --git a/bl2/aarch32/bl2_el3_entrypoint.S b/bl2/aarch32/bl2_el3_entrypoint.S index 7e855516d..40154aad6 100644 --- a/bl2/aarch32/bl2_el3_entrypoint.S +++ b/bl2/aarch32/bl2_el3_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,6 @@ #include .globl bl2_entrypoint - .globl bl2_run_next_image func bl2_entrypoint @@ -56,37 +55,3 @@ func bl2_entrypoint no_ret plat_panic_handler endfunc bl2_entrypoint - -func bl2_run_next_image - mov r8,r0 - - /* - * MMU needs to be disabled because both BL2 and BL32 execute - * in PL1, and therefore share the same address space. - * BL32 will initialize the address space according to its - * own requirement. - */ - bl disable_mmu_icache_secure - stcopr r0, TLBIALL - dsb sy - isb - mov r0, r8 - bl bl2_el3_plat_prepare_exit - - /* - * Extract PC and SPSR based on struct `entry_point_info_t` - * and load it in LR and SPSR registers respectively. - */ - ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] - ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] - msr spsr_xc, r1 - - /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ - cps #MODE32_svc - ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] - cps #MODE32_mon - - add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET - ldm r8, {r0, r1, r2, r3} - exception_return -endfunc bl2_run_next_image diff --git a/bl2/aarch32/bl2_run_next_image.S b/bl2/aarch32/bl2_run_next_image.S new file mode 100644 index 000000000..0b3554edc --- /dev/null +++ b/bl2/aarch32/bl2_run_next_image.S @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl bl2_run_next_image + + +func bl2_run_next_image + mov r8,r0 + + /* + * MMU needs to be disabled because both BL2 and BL32 execute + * in PL1, and therefore share the same address space. + * BL32 will initialize the address space according to its + * own requirement. + */ + bl disable_mmu_icache_secure + stcopr r0, TLBIALL + dsb sy + isb + mov r0, r8 + bl bl2_el3_plat_prepare_exit + + /* + * Extract PC and SPSR based on struct `entry_point_info_t` + * and load it in LR and SPSR registers respectively. + */ + ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] + ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] + msr spsr_xc, r1 + + /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ + cps #MODE32_svc + ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] + cps #MODE32_mon + + add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET + ldm r8, {r0, r1, r2, r3} + exception_return +endfunc bl2_run_next_image diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S index 4eab39cd3..45bac7da1 100644 --- a/bl2/aarch64/bl2_el3_entrypoint.S +++ b/bl2/aarch64/bl2_el3_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,8 +12,6 @@ #include .globl bl2_entrypoint - .globl bl2_el3_run_image - .globl bl2_run_next_image #if BL2_IN_XIP_MEM #define FIXUP_SIZE 0 @@ -72,36 +70,3 @@ func bl2_entrypoint */ no_ret plat_panic_handler endfunc bl2_entrypoint - -func bl2_run_next_image - mov x20,x0 - /* --------------------------------------------- - * MMU needs to be disabled because both BL2 and BL31 execute - * in EL3, and therefore share the same address space. - * BL31 will initialize the address space according to its - * own requirement. - * --------------------------------------------- - */ - bl disable_mmu_icache_el3 - tlbi alle3 - bl bl2_el3_plat_prepare_exit - -#if ENABLE_PAUTH - /* --------------------------------------------- - * Disable pointer authentication before jumping - * to next boot image. - * --------------------------------------------- - */ - bl pauth_disable_el3 -#endif /* ENABLE_PAUTH */ - - ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] - msr elr_el3, x0 - msr spsr_el3, x1 - - ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] - ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] - ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] - ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] - exception_return -endfunc bl2_run_next_image diff --git a/bl2/aarch64/bl2_rme_entrypoint.S b/bl2/aarch64/bl2_rme_entrypoint.S new file mode 100644 index 000000000..076e3267d --- /dev/null +++ b/bl2/aarch64/bl2_rme_entrypoint.S @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include + + .globl bl2_entrypoint + + +func bl2_entrypoint + /* Save arguments x0-x3 from previous Boot loader */ + mov x20, x0 + mov x21, x1 + mov x22, x2 + mov x23, x3 + + el3_entrypoint_common \ + _init_sctlr=0 \ + _warm_boot_mailbox=0 \ + _secondary_cold_boot=0 \ + _init_memory=0 \ + _init_c_runtime=1 \ + _exception_vectors=bl2_el3_exceptions \ + _pie_fixup_size=0 + + /* --------------------------------------------- + * Restore parameters of boot rom + * --------------------------------------------- + */ + mov x0, x20 + mov x1, x21 + mov x2, x22 + mov x3, x23 + + /* --------------------------------------------- + * Perform BL2 setup + * --------------------------------------------- + */ + bl bl2_setup + +#if ENABLE_PAUTH + /* --------------------------------------------- + * Program APIAKey_EL1 and enable pointer authentication. + * --------------------------------------------- + */ + bl pauth_init_enable_el3 +#endif /* ENABLE_PAUTH */ + + /* --------------------------------------------- + * Jump to main function. + * --------------------------------------------- + */ + bl bl2_main + + /* --------------------------------------------- + * Should never reach this point. + * --------------------------------------------- + */ + no_ret plat_panic_handler +endfunc bl2_entrypoint diff --git a/bl2/aarch64/bl2_run_next_image.S b/bl2/aarch64/bl2_run_next_image.S new file mode 100644 index 000000000..f0a8be87a --- /dev/null +++ b/bl2/aarch64/bl2_run_next_image.S @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + + .globl bl2_run_next_image + + +func bl2_run_next_image + mov x20,x0 + /* --------------------------------------------- + * MMU needs to be disabled because both BL2 and BL31 execute + * in EL3, and therefore share the same address space. + * BL31 will initialize the address space according to its + * own requirement. + * --------------------------------------------- + */ + bl disable_mmu_icache_el3 + tlbi alle3 + bl bl2_el3_plat_prepare_exit + +#if ENABLE_PAUTH + /* --------------------------------------------- + * Disable pointer authentication before jumping + * to next boot image. + * --------------------------------------------- + */ + bl pauth_disable_el3 +#endif /* ENABLE_PAUTH */ + + ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] + msr elr_el3, x0 + msr spsr_el3, x1 + + ldp x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)] + ldp x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)] + ldp x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)] + ldp x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)] + exception_return +endfunc bl2_run_next_image diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S index 37849c312..d332ec069 100644 --- a/bl2/bl2.ld.S +++ b/bl2/bl2.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,7 +25,11 @@ SECTIONS #if SEPARATE_CODE_AND_RODATA .text . : { __TEXT_START__ = .; +#if ENABLE_RME + *bl2_rme_entrypoint.o(.text*) +#else /* ENABLE_RME */ *bl2_entrypoint.o(.text*) +#endif /* ENABLE_RME */ *(SORT_BY_ALIGNMENT(.text*)) *(.vectors) . = ALIGN(PAGE_SIZE); diff --git a/bl2/bl2.mk b/bl2/bl2.mk index 735e7e04f..54c73f506 100644 --- a/bl2/bl2.mk +++ b/bl2/bl2.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -15,13 +15,24 @@ ifeq (${ARCH},aarch64) BL2_SOURCES += common/aarch64/early_exceptions.S endif -ifeq (${BL2_AT_EL3},0) +ifeq (${ENABLE_RME},1) +# Using RME, run BL2 at EL3 +BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \ + bl2/${ARCH}/bl2_el3_exceptions.S \ + bl2/${ARCH}/bl2_run_next_image.S \ + +BL2_LINKERFILE := bl2/bl2.ld.S + +else ifeq (${BL2_AT_EL3},0) +# Normal operation, no RME, no BL2 at EL3 BL2_SOURCES += bl2/${ARCH}/bl2_entrypoint.S BL2_LINKERFILE := bl2/bl2.ld.S else +# BL2 at EL3, no RME BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \ bl2/${ARCH}/bl2_el3_exceptions.S \ + bl2/${ARCH}/bl2_run_next_image.S \ lib/cpus/${ARCH}/cpu_helpers.S \ lib/cpus/errata_report.c diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index d2de1350d..197c057e1 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -29,18 +29,18 @@ #define NEXT_IMAGE "BL32" #endif -#if !BL2_AT_EL3 +#if BL2_AT_EL3 /******************************************************************************* - * Setup function for BL2. + * Setup function for BL2 when BL2_AT_EL3=1 ******************************************************************************/ -void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, - u_register_t arg3) +void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, + u_register_t arg3) { /* Perform early platform-specific setup */ - bl2_early_platform_setup2(arg0, arg1, arg2, arg3); + bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3); /* Perform late platform-specific setup */ - bl2_plat_arch_setup(); + bl2_el3_plat_arch_setup(); #if CTX_INCLUDE_PAUTH_REGS /* @@ -50,19 +50,18 @@ void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, assert(is_armv8_3_pauth_present()); #endif /* CTX_INCLUDE_PAUTH_REGS */ } - -#else /* if BL2_AT_EL3 */ +#else /* BL2_AT_EL3 */ /******************************************************************************* - * Setup function for BL2 when BL2_AT_EL3=1. + * Setup function for BL2 when BL2_AT_EL3=0 ******************************************************************************/ -void bl2_el3_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, - u_register_t arg3) +void bl2_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, + u_register_t arg3) { /* Perform early platform-specific setup */ - bl2_el3_early_platform_setup(arg0, arg1, arg2, arg3); + bl2_early_platform_setup2(arg0, arg1, arg2, arg3); /* Perform late platform-specific setup */ - bl2_el3_plat_arch_setup(); + bl2_plat_arch_setup(); #if CTX_INCLUDE_PAUTH_REGS /* @@ -115,7 +114,7 @@ void bl2_main(void) measured_boot_finish(); #endif /* MEASURED_BOOT */ -#if !BL2_AT_EL3 +#if !BL2_AT_EL3 && !ENABLE_RME #ifndef __aarch64__ /* * For AArch32 state BL1 and BL2 share the MMU setup. @@ -140,7 +139,7 @@ void bl2_main(void) * be passed to next BL image as an argument. */ smc(BL1_SMC_RUN_IMAGE, (unsigned long)next_bl_ep_info, 0, 0, 0, 0, 0, 0); -#else /* if BL2_AT_EL3 */ +#else /* if BL2_AT_EL3 || ENABLE_RME */ NOTICE("BL2: Booting " NEXT_IMAGE "\n"); print_entry_point_info(next_bl_ep_info); console_flush(); @@ -153,5 +152,5 @@ void bl2_main(void) #endif /* ENABLE_PAUTH */ bl2_run_next_image(next_bl_ep_info); -#endif /* BL2_AT_EL3 */ +#endif /* BL2_AT_EL3 && ENABLE_RME */ } diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index d4965841f..7d6a9638d 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -87,6 +87,13 @@ * do so. */ orr x0, x0, #(SCR_API_BIT | SCR_APK_BIT) +#endif +#if ENABLE_RME + /* + * TODO: Settting the EEL2 bit to allow EL3 access to secure only registers + * in context management. This will need to be refactored. + */ + orr x0, x0, #SCR_EEL2_BIT #endif msr scr_el3, x0 @@ -365,6 +372,7 @@ msr vbar_el3, x0 isb +#if !(defined(IMAGE_BL2) && ENABLE_RME) /* --------------------------------------------------------------------- * It is a cold boot. * Perform any processor specific actions upon reset e.g. cache, TLB @@ -372,6 +380,7 @@ * --------------------------------------------------------------------- */ bl reset_handler +#endif el3_arch_init_common @@ -414,7 +423,8 @@ * --------------------------------------------------------------------- */ .if \_init_c_runtime -#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_INV_DCACHE) +#if defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \ + ((BL2_AT_EL3 && BL2_INV_DCACHE) || ENABLE_RME)) /* ------------------------------------------------------------- * Invalidate the RW memory used by the BL31 image. This * includes the data and NOBITS sections. This is done to diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S index cc5c5759d..6e4d1fc30 100644 --- a/lib/aarch64/misc_helpers.S +++ b/lib/aarch64/misc_helpers.S @@ -163,7 +163,8 @@ func zeromem_dczva * Check for M bit (MMU enabled) of the current SCTLR_EL(1|3) * register value and panic if the MMU is disabled. */ -#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3) +#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && \ + (BL2_AT_EL3 || ENABLE_RME)) mrs tmp1, sctlr_el3 #else mrs tmp1, sctlr_el1 -- cgit v1.2.3 From 3202ce8bbb4af8580736d2a1634ad45c3f89d931 Mon Sep 17 00:00:00 2001 From: Alexei Fedorov Date: Wed, 1 Sep 2021 15:41:14 +0100 Subject: fix(fvp): fix fvp_cpu_standby() function The latest FVP model fix which correctly checks if IRQs are enabled in current exception level, is causing TFTF tests to hang. This patch adds setting SCR_EL3.I and SCR_EL3.F bits in 'fvp_cpu_standby()' function to allow CPU to exit from WFI. Signed-off-by: Alexei Fedorov Change-Id: Iceec1e9dbd805803d370ecdb10e04ad135d6b3aa --- plat/arm/board/fvp/fvp_pm.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 333d89288..6b9d6184c 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -138,21 +138,37 @@ static void fvp_power_domain_on_finish_common(const psci_power_state_t *target_s fvp_pwrc_clr_wen(mpidr); } - /******************************************************************************* * FVP handler called when a CPU is about to enter standby. ******************************************************************************/ static void fvp_cpu_standby(plat_local_state_t cpu_state) { + u_register_t scr = read_scr_el3(); assert(cpu_state == ARM_LOCAL_STATE_RET); /* - * Enter standby state - * dsb is good practice before using wfi to enter low power states + * Enable the Non-secure interrupt to wake the CPU. + * In GICv3 affinity routing mode, the Non-secure Group 1 interrupts + * use Physical FIQ at EL3 whereas in GICv2, Physical IRQ is used. + * Enabling both the bits works for both GICv2 mode and GICv3 affinity + * routing mode. + */ + write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); + isb(); + + /* + * Enter standby state. + * dsb is good practice before using wfi to enter low power states. */ dsb(); wfi(); + + /* + * Restore SCR_EL3 to the original value, synchronisation of SCR_EL3 + * is done by eret in el3_exit() to save some execution cycles. + */ + write_scr_el3(scr); } /******************************************************************************* -- cgit v1.2.3 From 77c2775323a5ff8b77230f05c0cc57f830e9f153 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 14:20:03 -0500 Subject: feat(rme): add RMM dispatcher (RMMD) This patch introduces the RMM dispatcher into BL31. This will be the mechanism that will enable communication to take place between the Realm and non-secure world. Currently gives the capability for granules to be transitioned from non-secure type to realm and vice versa. Signed-off-by: Zelalem Aweke Signed-off-by: Subhasish Ghosh Change-Id: I1fdc99a4bdd42bc14911aa0c6954b131de309511 --- bl31/bl31.mk | 4 + include/arch/aarch64/arch.h | 2 + include/services/gtsi_svc.h | 40 ++++ include/services/rmi_svc.h | 64 +++++ include/services/rmmd_svc.h | 34 +++ services/arm_arch_svc/arm_arch_svc_setup.c | 26 +- services/std_svc/rmmd/aarch64/rmmd_helpers.S | 73 ++++++ services/std_svc/rmmd/rmmd.mk | 13 + services/std_svc/rmmd/rmmd_initial_context.h | 33 +++ services/std_svc/rmmd/rmmd_main.c | 341 +++++++++++++++++++++++++++ services/std_svc/rmmd/rmmd_private.h | 64 +++++ services/std_svc/std_svc_setup.c | 12 + 12 files changed, 705 insertions(+), 1 deletion(-) create mode 100644 include/services/gtsi_svc.h create mode 100644 include/services/rmi_svc.h create mode 100644 include/services/rmmd_svc.h create mode 100644 services/std_svc/rmmd/aarch64/rmmd_helpers.S create mode 100644 services/std_svc/rmmd/rmmd.mk create mode 100644 services/std_svc/rmmd/rmmd_initial_context.h create mode 100644 services/std_svc/rmmd/rmmd_main.c create mode 100644 services/std_svc/rmmd/rmmd_private.h diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 7819141ef..ce0f69b7d 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -111,6 +111,10 @@ ifeq ($(SMC_PCI_SUPPORT),1) BL31_SOURCES += services/std_svc/pci_svc.c endif +ifeq (${ENABLE_RME},1) +BL31_SOURCES += ${RMMD_SOURCES} +endif + BL31_LINKERFILE := bl31/bl31.ld.S # Flag used to indicate if Crash reporting via console should be included diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 1053006a9..5949370e0 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -448,6 +448,7 @@ #define SCR_ECVEN_BIT (UL(1) << 28) #define SCR_FGTEN_BIT (UL(1) << 27) #define SCR_ATA_BIT (UL(1) << 26) +#define SCR_EnSCXT_BIT (UL(1) << 25) #define SCR_FIEN_BIT (UL(1) << 21) #define SCR_EEL2_BIT (UL(1) << 18) #define SCR_API_BIT (UL(1) << 17) @@ -609,6 +610,7 @@ #define SPSR_M_MASK U(0x1) #define SPSR_M_AARCH64 U(0x0) #define SPSR_M_AARCH32 U(0x1) +#define SPSR_M_EL2H U(0x9) #define SPSR_EL_SHIFT U(2) #define SPSR_EL_WIDTH U(2) diff --git a/include/services/gtsi_svc.h b/include/services/gtsi_svc.h new file mode 100644 index 000000000..cb942ed30 --- /dev/null +++ b/include/services/gtsi_svc.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GTSI_SVC_H +#define GTSI_SVC_H + +/* GTSI error codes. */ +#define GTSI_SUCCESS 0 +#define GTSI_ERROR_NOT_SUPPORTED -1 +#define GTSI_ERROR_INVALID_ADDRESS -2 +#define GTSI_ERROR_INVALID_PAS -3 + +/* The macros below are used to identify GTSI calls from the SMC function ID */ +#define GTSI_FNUM_MIN_VALUE U(0x100) +#define GTSI_FNUM_MAX_VALUE U(0x101) +#define is_gtsi_fid(fid) __extension__ ({ \ + __typeof__(fid) _fid = (fid); \ + ((GET_SMC_NUM(_fid) >= GTSI_FNUM_MIN_VALUE) && \ + (GET_SMC_NUM(_fid) <= GTSI_FNUM_MAX_VALUE)); }) + +/* Get GTSI fastcall std FID from function number */ +#define GTSI_FID(smc_cc, func_num) \ + ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \ + ((smc_cc) << FUNCID_CC_SHIFT) | \ + (OEN_STD_START << FUNCID_OEN_SHIFT) | \ + ((func_num) << FUNCID_NUM_SHIFT)) + +#define GRAN_TRANS_TO_REALM_FNUM U(0x100) +#define GRAN_TRANS_TO_NS_FNUM U(0x101) + +#define SMC_ASC_MARK_REALM GTSI_FID(SMC_64, GRAN_TRANS_TO_REALM_FNUM) +#define SMC_ASC_MARK_NONSECURE GTSI_FID(SMC_64, GRAN_TRANS_TO_NS_FNUM) + +#define GRAN_TRANS_RET_BAD_ADDR -2 +#define GRAN_TRANS_RET_BAD_PAS -3 + +#endif /* GTSI_SVC_H */ diff --git a/include/services/rmi_svc.h b/include/services/rmi_svc.h new file mode 100644 index 000000000..9106f088d --- /dev/null +++ b/include/services/rmi_svc.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RMI_SVC_H +#define RMI_SVC_H + +#include +#include + +/* RMI error codes. */ +#define RMI_SUCCESS 0 +#define RMI_ERROR_NOT_SUPPORTED -1 +#define RMI_ERROR_INVALID_ADDRESS -2 +#define RMI_ERROR_INVALID_PAS -3 + +/* The macros below are used to identify RMI calls from the SMC function ID */ +#define RMI_FNUM_MIN_VALUE U(0x00) +#define RMI_FNUM_MAX_VALUE U(0x20) +#define is_rmi_fid(fid) __extension__ ({ \ + __typeof__(fid) _fid = (fid); \ + ((GET_SMC_NUM(_fid) >= RMI_FNUM_MIN_VALUE) && \ + (GET_SMC_NUM(_fid) <= RMI_FNUM_MAX_VALUE) && \ + (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST) && \ + (GET_SMC_CC(_fid) == SMC_64) && \ + (GET_SMC_OEN(_fid) == OEN_ARM_START) && \ + ((_fid & 0x00FE0000) == 0U)); }) + +/* Get RMI fastcall std FID from function number */ +#define RMI_FID(smc_cc, func_num) \ + ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \ + ((smc_cc) << FUNCID_CC_SHIFT) | \ + (OEN_ARM_START << FUNCID_OEN_SHIFT) | \ + ((func_num) << FUNCID_NUM_SHIFT)) + +/* + * SMC_RMM_INIT_COMPLETE is the only function in the RMI that originates from + * the Realm world and is handled by the RMMD. The remaining functions are + * always invoked by the Normal world, forwarded by RMMD and handled by the + * RMM + */ +#define RMI_FNUM_REQ_COMPLETE U(0x10) +#define RMI_FNUM_VERSION_REQ U(0x00) + +#define RMI_FNUM_GRAN_NS_REALM U(0x01) +#define RMI_FNUM_GRAN_REALM_NS U(0x10) + +/* RMI SMC64 FIDs handled by the RMMD */ +#define RMI_RMM_REQ_COMPLETE RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE) +#define RMI_RMM_REQ_VERSION RMI_FID(SMC_64, RMI_FNUM_VERSION_REQ) + +#define RMI_RMM_GRANULE_DELEGATE RMI_FID(SMC_64, RMI_FNUM_GRAN_NS_REALM) +#define RMI_RMM_GRANULE_UNDELEGATE RMI_FID(SMC_64, RMI_FNUM_GRAN_REALM_NS) + + +#define RMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16) +#define RMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF) + +/* Reserve a special value for MBZ parameters. */ +#define RMI_PARAM_MBZ U(0x0) + +#endif /* RMI_SVC_H */ diff --git a/include/services/rmmd_svc.h b/include/services/rmmd_svc.h new file mode 100644 index 000000000..132973b77 --- /dev/null +++ b/include/services/rmmd_svc.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RMMD_SVC_H +#define RMMD_SVC_H + +#ifndef __ASSEMBLER__ +#include + +int rmmd_setup(void); +uint64_t rmmd_rmi_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags); + +uint64_t rmmd_gtsi_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags); + +#endif /* __ASSEMBLER__ */ + +#endif /* RMMD_SVC_H */ diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index 37bfc62e2..1d4423cb3 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,9 +11,19 @@ #include #include #include +#include +#include #include #include +#if ENABLE_RME +/* Setup Arm architecture Services */ +static int32_t arm_arch_svc_setup(void) +{ + return rmmd_setup(); +} +#endif + static int32_t smccc_version(void) { return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION); @@ -133,6 +143,16 @@ static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid, SMC_RET0(handle); #endif default: +#if ENABLE_RME + /* + * RMI functions are allocated from the Arch service range. Call + * the RMM dispatcher to handle RMI calls. + */ + if (is_rmi_fid(smc_fid)) { + return rmmd_rmi_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } +#endif WARN("Unimplemented Arm Architecture Service Call: 0x%x \n", smc_fid); SMC_RET1(handle, SMC_UNK); @@ -145,6 +165,10 @@ DECLARE_RT_SVC( OEN_ARM_START, OEN_ARM_END, SMC_TYPE_FAST, +#if ENABLE_RME + arm_arch_svc_setup, +#else NULL, +#endif arm_arch_svc_smc_handler ); diff --git a/services/std_svc/rmmd/aarch64/rmmd_helpers.S b/services/std_svc/rmmd/aarch64/rmmd_helpers.S new file mode 100644 index 000000000..6229baf4d --- /dev/null +++ b/services/std_svc/rmmd/aarch64/rmmd_helpers.S @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "../rmmd_private.h" +#include + + .global rmmd_rmm_enter + .global rmmd_rmm_exit + + /* --------------------------------------------------------------------- + * This function is called with SP_EL0 as stack. Here we stash our EL3 + * callee-saved registers on to the stack as a part of saving the C + * runtime and enter the secure payload. + * 'x0' contains a pointer to the memory where the address of the C + * runtime context is to be saved. + * --------------------------------------------------------------------- + */ +func rmmd_rmm_enter + /* Make space for the registers that we're going to save */ + mov x3, sp + str x3, [x0, #0] + sub sp, sp, #RMMD_C_RT_CTX_SIZE + + /* Save callee-saved registers on to the stack */ + stp x19, x20, [sp, #RMMD_C_RT_CTX_X19] + stp x21, x22, [sp, #RMMD_C_RT_CTX_X21] + stp x23, x24, [sp, #RMMD_C_RT_CTX_X23] + stp x25, x26, [sp, #RMMD_C_RT_CTX_X25] + stp x27, x28, [sp, #RMMD_C_RT_CTX_X27] + stp x29, x30, [sp, #RMMD_C_RT_CTX_X29] + + /* --------------------------------------------------------------------- + * Everything is setup now. el3_exit() will use the secure context to + * restore to the general purpose and EL3 system registers to ERET + * into the secure payload. + * --------------------------------------------------------------------- + */ + b el3_exit +endfunc rmmd_rmm_enter + + /* --------------------------------------------------------------------- + * This function is called with 'x0' pointing to a C runtime context. + * It restores the saved registers and jumps to that runtime with 'x0' + * as the new SP register. This destroys the C runtime context that had + * been built on the stack below the saved context by the caller. Later + * the second parameter 'x1' is passed as a return value to the caller. + * --------------------------------------------------------------------- + */ +func rmmd_rmm_exit + /* Restore the previous stack */ + mov sp, x0 + + /* Restore callee-saved registers on to the stack */ + ldp x19, x20, [x0, #(RMMD_C_RT_CTX_X19 - RMMD_C_RT_CTX_SIZE)] + ldp x21, x22, [x0, #(RMMD_C_RT_CTX_X21 - RMMD_C_RT_CTX_SIZE)] + ldp x23, x24, [x0, #(RMMD_C_RT_CTX_X23 - RMMD_C_RT_CTX_SIZE)] + ldp x25, x26, [x0, #(RMMD_C_RT_CTX_X25 - RMMD_C_RT_CTX_SIZE)] + ldp x27, x28, [x0, #(RMMD_C_RT_CTX_X27 - RMMD_C_RT_CTX_SIZE)] + ldp x29, x30, [x0, #(RMMD_C_RT_CTX_X29 - RMMD_C_RT_CTX_SIZE)] + + /* --------------------------------------------------------------------- + * This should take us back to the instruction after the call to the + * last rmmd_rmm_enter().* Place the second parameter to x0 + * so that the caller will see it as a return value from the original + * entry call. + * --------------------------------------------------------------------- + */ + mov x0, x1 + ret +endfunc rmmd_rmm_exit diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk new file mode 100644 index 000000000..57031fe17 --- /dev/null +++ b/services/std_svc/rmmd/rmmd.mk @@ -0,0 +1,13 @@ +# +# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +ifneq (${ARCH},aarch64) + $(error "Error: RMMD is only supported on aarch64.") +endif + +RMMD_SOURCES += $(addprefix services/std_svc/rmmd/, \ + ${ARCH}/rmmd_helpers.S \ + rmmd_main.c) diff --git a/services/std_svc/rmmd/rmmd_initial_context.h b/services/std_svc/rmmd/rmmd_initial_context.h new file mode 100644 index 000000000..d7a743d8e --- /dev/null +++ b/services/std_svc/rmmd/rmmd_initial_context.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RMMD_INITIAL_CONTEXT_H +#define RMMD_INITIAL_CONTEXT_H + +#include + +/* + * SPSR_EL2 + * M=0x9 (0b1001 EL2h) + * M[4]=0 + * DAIF=0xF Exceptions masked on entry. + * BTYPE=0 BTI not yet supported. + * SSBS=0 Not yet supported. + * IL=0 Not an illegal exception return. + * SS=0 Not single stepping. + * PAN=1 RMM shouldn't access realm memory. + * UAO=0 + * DIT=0 + * TCO=0 + * NZCV=0 + */ +#define REALM_SPSR_EL2 ( \ + SPSR_M_EL2H | \ + (0xF << SPSR_DAIF_SHIFT) | \ + SPSR_PAN_BIT \ + ) + +#endif /* RMMD_INITIAL_CONTEXT_H */ diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c new file mode 100644 index 000000000..26a5b8464 --- /dev/null +++ b/services/std_svc/rmmd/rmmd_main.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmmd_initial_context.h" +#include "rmmd_private.h" + +/******************************************************************************* + * RMM context information. + ******************************************************************************/ +rmmd_rmm_context_t rmm_context[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * RMM entry point information. Discovered on the primary core and reused + * on secondary cores. + ******************************************************************************/ +static entry_point_info_t *rmm_ep_info; + +/******************************************************************************* + * Static function declaration. + ******************************************************************************/ +static int32_t rmm_init(void); +static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state, + uint32_t dst_sec_state, uint64_t x1, + uint64_t x2, uint64_t x3, uint64_t x4, + void *handle); + +/******************************************************************************* + * This function takes an RMM context pointer and performs a synchronous entry + * into it. + ******************************************************************************/ +uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *rmm_ctx) +{ + uint64_t rc; + + assert(rmm_ctx != NULL); + + cm_set_context(&(rmm_ctx->cpu_ctx), REALM); + + /* Save the current el1/el2 context before loading realm context. */ + cm_el1_sysregs_context_save(NON_SECURE); + cm_el2_sysregs_context_save(NON_SECURE); + + /* Restore the realm context assigned above */ + cm_el1_sysregs_context_restore(REALM); + cm_el2_sysregs_context_restore(REALM); + cm_set_next_eret_context(REALM); + + /* Enter RMM */ + rc = rmmd_rmm_enter(&rmm_ctx->c_rt_ctx); + + /* Save realm context */ + cm_el1_sysregs_context_save(REALM); + cm_el2_sysregs_context_save(REALM); + + /* Restore the el1/el2 context again. */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_el2_sysregs_context_restore(NON_SECURE); + + return rc; +} + +/******************************************************************************* + * This function returns to the place where rmmd_rmm_sync_entry() was + * called originally. + ******************************************************************************/ +__dead2 void rmmd_rmm_sync_exit(uint64_t rc) +{ + rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()]; + + /* Get context of the RMM in use by this CPU. */ + assert(cm_get_context(REALM) == &(ctx->cpu_ctx)); + + /* + * The RMMD must have initiated the original request through a + * synchronous entry into RMM. Jump back to the original C runtime + * context with the value of rc in x0; + */ + rmmd_rmm_exit(ctx->c_rt_ctx, rc); + + panic(); +} + +static void rmm_el2_context_init(el2_sysregs_t *regs) +{ + regs->ctx_regs[CTX_SPSR_EL2 >> 3] = REALM_SPSR_EL2; + regs->ctx_regs[CTX_SCTLR_EL2 >> 3] = SCTLR_EL2_RES1; +} + +/******************************************************************************* + * Jump to the RMM for the first time. + ******************************************************************************/ +static int32_t rmm_init(void) +{ + + uint64_t rc; + + rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()]; + + INFO("RMM init start.\n"); + ctx->state = RMM_STATE_RESET; + + /* Initialize RMM EL2 context. */ + rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx); + + rc = rmmd_rmm_sync_entry(ctx); + if (rc != 0ULL) { + ERROR("RMM initialisation failed 0x%llx\n", rc); + panic(); + } + + ctx->state = RMM_STATE_IDLE; + INFO("RMM init end.\n"); + + return 1; +} + +/******************************************************************************* + * Load and read RMM manifest, setup RMM. + ******************************************************************************/ +int rmmd_setup(void) +{ + uint32_t ep_attr; + unsigned int linear_id = plat_my_core_pos(); + rmmd_rmm_context_t *rmm_ctx = &rmm_context[linear_id]; + + /* Make sure RME is supported. */ + assert(get_armv9_2_feat_rme_support() != 0U); + + rmm_ep_info = bl31_plat_get_next_image_ep_info(REALM); + if (rmm_ep_info == NULL) { + WARN("No RMM image provided by BL2 boot loader, Booting " + "device without RMM initialization. SMCs destined for " + "RMM will return SMC_UNK\n"); + return -ENOENT; + } + + /* Under no circumstances will this parameter be 0 */ + assert(rmm_ep_info->pc == RMM_BASE); + + /* Initialise an entrypoint to set up the CPU context */ + ep_attr = EP_REALM; + if ((read_sctlr_el3() & SCTLR_EE_BIT) != 0U) { + ep_attr |= EP_EE_BIG; + } + + SET_PARAM_HEAD(rmm_ep_info, PARAM_EP, VERSION_1, ep_attr); + rmm_ep_info->spsr = SPSR_64(MODE_EL2, + MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); + + /* Initialise RMM context with this entry point information */ + cm_setup_context(&rmm_ctx->cpu_ctx, rmm_ep_info); + + INFO("RMM setup done.\n"); + + /* Register init function for deferred init. */ + bl31_register_rmm_init(&rmm_init); + + return 0; +} + +/******************************************************************************* + * Forward SMC to the other security state + ******************************************************************************/ +static uint64_t rmmd_smc_forward(uint32_t smc_fid, uint32_t src_sec_state, + uint32_t dst_sec_state, uint64_t x1, + uint64_t x2, uint64_t x3, uint64_t x4, + void *handle) +{ + /* Save incoming security state */ + cm_el1_sysregs_context_save(src_sec_state); + cm_el2_sysregs_context_save(src_sec_state); + + /* Restore outgoing security state */ + cm_el1_sysregs_context_restore(dst_sec_state); + cm_el2_sysregs_context_restore(dst_sec_state); + cm_set_next_eret_context(dst_sec_state); + + SMC_RET8(cm_get_context(dst_sec_state), smc_fid, x1, x2, x3, x4, + SMC_GET_GP(handle, CTX_GPREG_X5), + SMC_GET_GP(handle, CTX_GPREG_X6), + SMC_GET_GP(handle, CTX_GPREG_X7)); +} + +/******************************************************************************* + * This function handles all SMCs in the range reserved for RMI. Each call is + * either forwarded to the other security state or handled by the RMM dispatcher + ******************************************************************************/ +uint64_t rmmd_rmi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, void *cookie, + void *handle, uint64_t flags) +{ + rmmd_rmm_context_t *ctx = &rmm_context[plat_my_core_pos()]; + uint32_t src_sec_state; + + /* Determine which security state this SMC originated from */ + src_sec_state = caller_sec_state(flags); + + /* RMI must not be invoked by the Secure world */ + if (src_sec_state == SMC_FROM_SECURE) { + WARN("RMM: RMI invoked by secure world.\n"); + SMC_RET1(handle, SMC_UNK); + } + + /* + * Forward an RMI call from the Normal world to the Realm world as it + * is. + */ + if (src_sec_state == SMC_FROM_NON_SECURE) { + VERBOSE("RMM: RMI call from non-secure world.\n"); + return rmmd_smc_forward(smc_fid, NON_SECURE, REALM, + x1, x2, x3, x4, handle); + } + + assert(src_sec_state == SMC_FROM_REALM); + + switch (smc_fid) { + case RMI_RMM_REQ_COMPLETE: + if (ctx->state == RMM_STATE_RESET) { + VERBOSE("RMM: running rmmd_rmm_sync_exit\n"); + rmmd_rmm_sync_exit(x1); + } + + return rmmd_smc_forward(x1, REALM, NON_SECURE, + x2, x3, x4, 0, handle); + + default: + WARN("RMM: Unsupported RMM call 0x%08x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} + +/******************************************************************************* + * This cpu has been turned on. Enter RMM to initialise R-EL2. Entry into RMM + * is done after initialising minimal architectural state that guarantees safe + * execution. + ******************************************************************************/ +static void *rmmd_cpu_on_finish_handler(const void *arg) +{ + int32_t rc; + uint32_t linear_id = plat_my_core_pos(); + rmmd_rmm_context_t *ctx = &rmm_context[linear_id]; + + ctx->state = RMM_STATE_RESET; + + /* Initialise RMM context with this entry point information */ + cm_setup_context(&ctx->cpu_ctx, rmm_ep_info); + + /* Initialize RMM EL2 context. */ + rmm_el2_context_init(&ctx->cpu_ctx.el2_sysregs_ctx); + + rc = rmmd_rmm_sync_entry(ctx); + if (rc != 0) { + ERROR("RMM initialisation failed (%d) on CPU%d\n", rc, + linear_id); + panic(); + } + + ctx->state = RMM_STATE_IDLE; + return NULL; +} + +/* Subscribe to PSCI CPU on to initialize RMM on secondary */ +SUBSCRIBE_TO_EVENT(psci_cpu_on_finish, rmmd_cpu_on_finish_handler); + +static int gtsi_transition_granule(uint64_t pa, + unsigned int src_sec_state, + unsigned int target_pas) +{ + int ret; + + ret = gpt_transition_pas(pa, src_sec_state, target_pas); + + /* Convert TF-A error codes into GTSI error codes */ + if (ret == -EINVAL) { + ret = GRAN_TRANS_RET_BAD_ADDR; + } else if (ret == -EPERM) { + ret = GRAN_TRANS_RET_BAD_PAS; + } + + return ret; +} + +/******************************************************************************* + * This function handles all SMCs in the range reserved for GTF. + ******************************************************************************/ +uint64_t rmmd_gtsi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, + uint64_t x3, uint64_t x4, void *cookie, + void *handle, uint64_t flags) +{ + uint32_t src_sec_state; + + /* Determine which security state this SMC originated from */ + src_sec_state = caller_sec_state(flags); + + if (src_sec_state != SMC_FROM_REALM) { + WARN("RMM: GTF call originated from secure or normal world\n"); + SMC_RET1(handle, SMC_UNK); + } + + switch (smc_fid) { + case SMC_ASC_MARK_REALM: + SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM, + GPI_REALM)); + break; + case SMC_ASC_MARK_NONSECURE: + SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM, + GPI_NS)); + break; + default: + WARN("RMM: Unsupported GTF call 0x%08x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} diff --git a/services/std_svc/rmmd/rmmd_private.h b/services/std_svc/rmmd/rmmd_private.h new file mode 100644 index 000000000..d170bcd22 --- /dev/null +++ b/services/std_svc/rmmd/rmmd_private.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RMMD_PRIVATE_H +#define RMMD_PRIVATE_H + +#include + +/******************************************************************************* + * Constants that allow assembler code to preserve callee-saved registers of the + * C runtime context while performing a security state switch. + ******************************************************************************/ +#define RMMD_C_RT_CTX_X19 0x0 +#define RMMD_C_RT_CTX_X20 0x8 +#define RMMD_C_RT_CTX_X21 0x10 +#define RMMD_C_RT_CTX_X22 0x18 +#define RMMD_C_RT_CTX_X23 0x20 +#define RMMD_C_RT_CTX_X24 0x28 +#define RMMD_C_RT_CTX_X25 0x30 +#define RMMD_C_RT_CTX_X26 0x38 +#define RMMD_C_RT_CTX_X27 0x40 +#define RMMD_C_RT_CTX_X28 0x48 +#define RMMD_C_RT_CTX_X29 0x50 +#define RMMD_C_RT_CTX_X30 0x58 + +#define RMMD_C_RT_CTX_SIZE 0x60 +#define RMMD_C_RT_CTX_ENTRIES (RMMD_C_RT_CTX_SIZE >> DWORD_SHIFT) + +#ifndef __ASSEMBLER__ +#include +#include + +typedef enum rmm_state { + RMM_STATE_RESET = 0, + RMM_STATE_IDLE +} rmm_state_t; + +/* + * Data structure used by the RMM dispatcher (RMMD) in EL3 to track context of + * the RMM at R-EL2. + */ +typedef struct rmmd_rmm_context { + uint64_t c_rt_ctx; + cpu_context_t cpu_ctx; + rmm_state_t state; +} rmmd_rmm_context_t; + +/* Functions used to enter/exit the RMM synchronously */ +uint64_t rmmd_rmm_sync_entry(rmmd_rmm_context_t *ctx); +__dead2 void rmmd_rmm_sync_exit(uint64_t rc); + +/* Assembly helpers */ +uint64_t rmmd_rmm_enter(uint64_t *c_rt_ctx); +void __dead2 rmmd_rmm_exit(uint64_t c_rt_ctx, uint64_t ret); + +/* Reference to PM ops for the RMMD */ +extern const spd_pm_ops_t rmmd_pm; + +#endif /* __ASSEMBLER__ */ + +#endif /* RMMD_PRIVATE_H */ diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 1917d0a14..39db42913 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -158,6 +160,16 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid, flags); } #endif +#if ENABLE_RME + /* + * Granule transition service interface functions (GTSI) are allocated + * from the Std service range. Call the RMM dispatcher to handle calls. + */ + if (is_gtsi_fid(smc_fid)) { + return rmmd_gtsi_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } +#endif #if SMC_PCI_SUPPORT if (is_pci_fid(smc_fid)) { -- cgit v1.2.3 From 50a3056a3cd33d395e8712e1d1e67a8840bf3db1 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 15:32:21 -0500 Subject: feat(rme): add Test Realm Payload (TRP) TRP is a small test payload that implements Realm Monitor Management (RMM) functionalities. RMM runs in the Realm world (R-EL2) and manages the execution of Realm VMs and their interaction with the hypervisor in Normal world. TRP is used to test the interface between RMM and Normal world software, known as Realm Management Interface (RMI). Current functions includes returning RMM version and transitioning granules from Non-secure to Realm world and vice versa. More information about RMM can be found at: https://developer.arm.com/documentation/den0125/latest Signed-off-by: Zelalem Aweke Change-Id: Ic7b9a1e1f3142ef6458d40150d0b4ba6bd723ea2 --- include/services/trp/platform_trp.h | 15 ++++ plat/arm/board/fvp/include/platform_def.h | 3 + plat/arm/board/fvp/trp/trp-fvp.mk | 12 +++ plat/arm/common/trp/arm_trp.mk | 10 +++ plat/arm/common/trp/arm_trp_setup.c | 40 +++++++++ services/std_svc/rmmd/rmmd.mk | 3 + services/std_svc/rmmd/trp/linker.lds | 71 ++++++++++++++++ services/std_svc/rmmd/trp/trp.mk | 20 +++++ services/std_svc/rmmd/trp/trp_entry.S | 74 ++++++++++++++++ services/std_svc/rmmd/trp/trp_main.c | 136 ++++++++++++++++++++++++++++++ services/std_svc/rmmd/trp/trp_private.h | 50 +++++++++++ 11 files changed, 434 insertions(+) create mode 100644 include/services/trp/platform_trp.h create mode 100644 plat/arm/board/fvp/trp/trp-fvp.mk create mode 100644 plat/arm/common/trp/arm_trp.mk create mode 100644 plat/arm/common/trp/arm_trp_setup.c create mode 100644 services/std_svc/rmmd/trp/linker.lds create mode 100644 services/std_svc/rmmd/trp/trp.mk create mode 100644 services/std_svc/rmmd/trp/trp_entry.S create mode 100644 services/std_svc/rmmd/trp/trp_main.c create mode 100644 services/std_svc/rmmd/trp/trp_private.h diff --git a/include/services/trp/platform_trp.h b/include/services/trp/platform_trp.h new file mode 100644 index 000000000..b34da8512 --- /dev/null +++ b/include/services/trp/platform_trp.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_TRP_H +#define PLATFORM_TRP_H + +/******************************************************************************* + * Mandatory TRP functions (only if platform contains a TRP) + ******************************************************************************/ +void trp_early_platform_setup(void); + +#endif /* PLATFORM_TRP_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 8b25a5463..a716546a4 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -222,6 +222,9 @@ #define PLAT_ARM_TSP_UART_BASE V2M_IOFPGA_UART2_BASE #define PLAT_ARM_TSP_UART_CLK_IN_HZ V2M_IOFPGA_UART2_CLK_IN_HZ +#define PLAT_ARM_TRP_UART_BASE V2M_IOFPGA_UART3_BASE +#define PLAT_ARM_TRP_UART_CLK_IN_HZ V2M_IOFPGA_UART3_CLK_IN_HZ + #define PLAT_FVP_SMMUV3_BASE UL(0x2b400000) /* CCI related constants */ diff --git a/plat/arm/board/fvp/trp/trp-fvp.mk b/plat/arm/board/fvp/trp/trp-fvp.mk new file mode 100644 index 000000000..a450541d3 --- /dev/null +++ b/plat/arm/board/fvp/trp/trp-fvp.mk @@ -0,0 +1,12 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# TRP source files specific to FVP platform + +RMM_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S + +include plat/arm/common/trp/arm_trp.mk + diff --git a/plat/arm/common/trp/arm_trp.mk b/plat/arm/common/trp/arm_trp.mk new file mode 100644 index 000000000..997111f99 --- /dev/null +++ b/plat/arm/common/trp/arm_trp.mk @@ -0,0 +1,10 @@ +# +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# TRP source files common to ARM standard platforms +RMM_SOURCES += plat/arm/common/trp/arm_trp_setup.c \ + plat/arm/common/arm_topology.c \ + plat/common/aarch64/platform_mp_stack.S diff --git a/plat/arm/common/trp/arm_trp_setup.c b/plat/arm/common/trp/arm_trp_setup.c new file mode 100644 index 000000000..8e4829344 --- /dev/null +++ b/plat/arm/common/trp/arm_trp_setup.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/******************************************************************************* + * Initialize the UART + ******************************************************************************/ +static console_t arm_trp_runtime_console; + +void arm_trp_early_platform_setup(void) +{ + /* + * Initialize a different console than already in use to display + * messages from trp + */ + int rc = console_pl011_register(PLAT_ARM_TRP_UART_BASE, + PLAT_ARM_TRP_UART_CLK_IN_HZ, + ARM_CONSOLE_BAUDRATE, + &arm_trp_runtime_console); + if (rc == 0) { + panic(); + } + + console_set_scope(&arm_trp_runtime_console, + CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); +} + +void trp_early_platform_setup(void) +{ + arm_trp_early_platform_setup(); +} diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk index 57031fe17..b42568183 100644 --- a/services/std_svc/rmmd/rmmd.mk +++ b/services/std_svc/rmmd/rmmd.mk @@ -8,6 +8,9 @@ ifneq (${ARCH},aarch64) $(error "Error: RMMD is only supported on aarch64.") endif +include services/std_svc/rmmd/trp/trp.mk + RMMD_SOURCES += $(addprefix services/std_svc/rmmd/, \ ${ARCH}/rmmd_helpers.S \ rmmd_main.c) + diff --git a/services/std_svc/rmmd/trp/linker.lds b/services/std_svc/rmmd/trp/linker.lds new file mode 100644 index 000000000..2b7f38333 --- /dev/null +++ b/services/std_svc/rmmd/trp/linker.lds @@ -0,0 +1,71 @@ +/* + * (C) COPYRIGHT 2021 Arm Limited or its affiliates. + * ALL RIGHTS RESERVED + */ + +#include +#include + +/* Mapped using 4K pages, requires us to align different sections with + * different property at the same granularity. */ +PAGE_SIZE_4K = 4096; + +OUTPUT_FORMAT("elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(trp_head) + +MEMORY { + RAM (rwx): ORIGIN = RMM_BASE, LENGTH = RMM_LIMIT - RMM_BASE +} + + +SECTIONS +{ + . = RMM_BASE; + + .text : { + *(.head.text) + . = ALIGN(8); + *(.text*) + } >RAM + + . = ALIGN(PAGE_SIZE_4K); + + .rodata : { + *(.rodata*) + } >RAM + + . = ALIGN(PAGE_SIZE_4K); + + __RW_START__ = . ; + + .data : { + *(.data*) + } >RAM + + .bss (NOLOAD) : { + __BSS_START__ = .; + *(.bss*) + __BSS_END__ = .; + } >RAM + __BSS_SIZE__ = SIZEOF(.bss); + + + STACK_SECTION >RAM + + + /* + * Define a linker symbol to mark the end of the RW memory area for this + * image. + */ + __RW_END__ = .; + __RMM_END__ = .; + + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } + /DISCARD/ : { *(.note*) } +} diff --git a/services/std_svc/rmmd/trp/trp.mk b/services/std_svc/rmmd/trp/trp.mk new file mode 100644 index 000000000..a4f6e03e0 --- /dev/null +++ b/services/std_svc/rmmd/trp/trp.mk @@ -0,0 +1,20 @@ +# +# Copyright (c) 2021 Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +RMM_SOURCES += services/std_svc/rmmd/trp/trp_entry.S \ + services/std_svc/rmmd/trp/trp_main.c + +RMM_LINKERFILE := services/std_svc/rmmd/trp/linker.lds + +# Include the platform-specific TRP Makefile +# If no platform-specific TRP Makefile exists, it means TRP is not supported +# on this platform. +TRP_PLAT_MAKEFILE := $(wildcard ${PLAT_DIR}/trp/trp-${PLAT}.mk) +ifeq (,${TRP_PLAT_MAKEFILE}) + $(error TRP is not supported on platform ${PLAT}) +else + include ${TRP_PLAT_MAKEFILE} +endif diff --git a/services/std_svc/rmmd/trp/trp_entry.S b/services/std_svc/rmmd/trp/trp_entry.S new file mode 100644 index 000000000..23b48fb42 --- /dev/null +++ b/services/std_svc/rmmd/trp/trp_entry.S @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include "trp_private.h" + +.global trp_head +.global trp_smc + +.section ".head.text", "ax" + + /* --------------------------------------------- + * Populate the params in x0-x7 from the pointer + * to the smc args structure in x0. + * --------------------------------------------- + */ + .macro restore_args_call_smc + ldp x6, x7, [x0, #TRP_ARG6] + ldp x4, x5, [x0, #TRP_ARG4] + ldp x2, x3, [x0, #TRP_ARG2] + ldp x0, x1, [x0, #TRP_ARG0] + smc #0 + .endm + + /* --------------------------------------------- + * Entry point for TRP + * --------------------------------------------- + */ +trp_head: + bl plat_set_my_stack + bl plat_is_my_cpu_primary + cbz x0, trp_secondary_cpu_entry + + /* --------------------------------------------- + * Zero out BSS section + * --------------------------------------------- + */ + ldr x0, =__BSS_START__ + ldr x1, =__BSS_SIZE__ + bl zeromem + + bl trp_setup + + bl trp_main +trp_secondary_cpu_entry: + mov_imm x0, RMI_RMM_REQ_COMPLETE + mov x1, xzr + smc #0 + b trp_handler + + /* --------------------------------------------- + * Direct SMC call to BL31 service provided by + * RMM Dispatcher + * --------------------------------------------- + */ +func trp_smc + restore_args_call_smc + ret +endfunc trp_smc + + /* --------------------------------------------- + * RMI call handler + * --------------------------------------------- + */ +func trp_handler + bl trp_rmi_handler + restore_args_call_smc + b trp_handler +endfunc trp_handler diff --git a/services/std_svc/rmmd/trp/trp_main.c b/services/std_svc/rmmd/trp/trp_main.c new file mode 100644 index 000000000..2ab9eccfd --- /dev/null +++ b/services/std_svc/rmmd/trp/trp_main.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#include +#include +#include +#include +#include + +#include +#include "trp_private.h" + +/******************************************************************************* + * Per cpu data structure to populate parameters for an SMC in C code and use + * a pointer to this structure in assembler code to populate x0-x7 + ******************************************************************************/ +static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT]; + +/******************************************************************************* + * Set the arguments for SMC call + ******************************************************************************/ +static trp_args_t *set_smc_args(uint64_t arg0, + uint64_t arg1, + uint64_t arg2, + uint64_t arg3, + uint64_t arg4, + uint64_t arg5, + uint64_t arg6, + uint64_t arg7) +{ + uint32_t linear_id; + trp_args_t *pcpu_smc_args; + + /* + * Return to Secure Monitor by raising an SMC. The results of the + * service are passed as an arguments to the SMC + */ + linear_id = plat_my_core_pos(); + pcpu_smc_args = &trp_smc_args[linear_id]; + write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0); + write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1); + write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2); + write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3); + write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4); + write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5); + write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6); + write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7); + + return pcpu_smc_args; +} + +/******************************************************************************* + * Setup function for TRP. + ******************************************************************************/ +void trp_setup(void) +{ + /* Perform early platform-specific setup */ + trp_early_platform_setup(); +} + +/* Main function for TRP */ +void trp_main(void) +{ + NOTICE("TRP: %s\n", version_string); + NOTICE("TRP: %s\n", build_message); + INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); + INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END + - RMM_BASE)); +} + +/******************************************************************************* + * Returning RMI version back to Normal World + ******************************************************************************/ +static trp_args_t *trp_ret_rmi_version(void) +{ + VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR, + RMI_ABI_VERSION_MINOR); + return set_smc_args(RMI_RMM_REQ_COMPLETE, RMI_ABI_VERSION, + 0, 0, 0, 0, 0, 0); +} + +/******************************************************************************* + * Transitioning granule of NON-SECURE type to REALM type + ******************************************************************************/ +static trp_args_t *trp_asc_mark_realm(unsigned long long x1) +{ + unsigned long long ret; + + VERBOSE("Delegating granule 0x%llx\n", x1); + ret = trp_smc(set_smc_args(SMC_ASC_MARK_REALM, x1, 0, 0, 0, 0, 0, 0)); + + if (ret != 0ULL) { + ERROR("Granule transition from NON-SECURE type to REALM type " + "failed 0x%llx\n", ret); + } + return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); +} + +/******************************************************************************* + * Transitioning granule of REALM type to NON-SECURE type + ******************************************************************************/ +static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1) +{ + unsigned long long ret; + + VERBOSE("Undelegating granule 0x%llx\n", x1); + ret = trp_smc(set_smc_args(SMC_ASC_MARK_NONSECURE, x1, 0, 0, 0, 0, 0, 0)); + + if (ret != 0ULL) { + ERROR("Granule transition from REALM type to NON-SECURE type " + "failed 0x%llx\n", ret); + } + return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); +} + +/******************************************************************************* + * Main RMI SMC handler function + ******************************************************************************/ +trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) +{ + switch (fid) { + case RMI_RMM_REQ_VERSION: + return trp_ret_rmi_version(); + case RMI_RMM_GRANULE_DELEGATE: + return trp_asc_mark_realm(x1); + case RMI_RMM_GRANULE_UNDELEGATE: + return trp_asc_mark_nonsecure(x1); + default: + ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); + } + return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); +} diff --git a/services/std_svc/rmmd/trp/trp_private.h b/services/std_svc/rmmd/trp/trp_private.h new file mode 100644 index 000000000..923139007 --- /dev/null +++ b/services/std_svc/rmmd/trp/trp_private.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TRP_PRIVATE_H +#define TRP_PRIVATE_H + +/* Definitions to help the assembler access the SMC/ERET args structure */ +#define TRP_ARGS_SIZE TRP_ARGS_END +#define TRP_ARG0 0x0 +#define TRP_ARG1 0x8 +#define TRP_ARG2 0x10 +#define TRP_ARG3 0x18 +#define TRP_ARG4 0x20 +#define TRP_ARG5 0x28 +#define TRP_ARG6 0x30 +#define TRP_ARG7 0x38 +#define TRP_ARGS_END 0x40 + +#ifndef __ASSEMBLER__ + +#include + +/* Data structure to hold SMC arguments */ +typedef struct trp_args { + uint64_t regs[TRP_ARGS_END >> 3]; +} __aligned(CACHE_WRITEBACK_GRANULE) trp_args_t; + +#define write_trp_arg(args, offset, val) (((args)->regs[offset >> 3]) \ + = val) + +/* Definitions for RMI VERSION */ +#define RMI_ABI_VERSION_MAJOR U(0x0) +#define RMI_ABI_VERSION_MINOR U(0x0) +#define RMI_ABI_VERSION ((RMI_ABI_VERSION_MAJOR << 16) | \ + RMI_ABI_VERSION_MINOR) + +/* Helper to issue SMC calls to BL31 */ +uint64_t trp_smc(trp_args_t *); + +/* The main function to executed only by Primary CPU */ +void trp_main(void); + +/* Setup TRP. Executed only by Primary CPU */ +void trp_setup(void); + +#endif /* __ASSEMBLER__ */ +#endif /* TRP_PRIVATE_H */ -- cgit v1.2.3 From c5ea4f8a6679131010636eb524d2a15b709d0196 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 9 Jul 2021 17:54:30 -0500 Subject: feat(rme): add context management changes for FEAT_RME This patch adds a new context for realm world and realm world awareness in context management. Signed-off-by: Zelalem Aweke Signed-off-by: Subhasish Ghosh Change-Id: Ic17469393603e789d7adc025880346bc3d6233d7 --- bl31/bl31_context_mgmt.c | 18 +++++--- include/lib/el3_runtime/aarch64/context.h | 13 +++--- include/lib/el3_runtime/cpu_data.h | 73 ++++++++++++++++++++++++++----- lib/el3_runtime/aarch64/context_mgmt.c | 51 +++++++++++++++------ 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/bl31/bl31_context_mgmt.c b/bl31/bl31_context_mgmt.c index 9175ee35d..34f69ade9 100644 --- a/bl31/bl31_context_mgmt.c +++ b/bl31/bl31_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,9 +19,9 @@ ******************************************************************************/ void *cm_get_context(uint32_t security_state) { - assert(security_state <= NON_SECURE); + assert(sec_state_is_valid(security_state)); - return get_cpu_data(cpu_context[security_state]); + return get_cpu_data(cpu_context[get_cpu_context_index(security_state)]); } /******************************************************************************* @@ -30,9 +30,10 @@ void *cm_get_context(uint32_t security_state) ******************************************************************************/ void cm_set_context(void *context, uint32_t security_state) { - assert(security_state <= NON_SECURE); + assert(sec_state_is_valid(security_state)); - set_cpu_data(cpu_context[security_state], context); + set_cpu_data(cpu_context[get_cpu_context_index(security_state)], + context); } /******************************************************************************* @@ -46,7 +47,8 @@ void *cm_get_context_by_index(unsigned int cpu_idx, { assert(sec_state_is_valid(security_state)); - return get_cpu_data_by_index(cpu_idx, cpu_context[security_state]); + return get_cpu_data_by_index(cpu_idx, + cpu_context[get_cpu_context_index(security_state)]); } /******************************************************************************* @@ -58,5 +60,7 @@ void cm_set_context_by_index(unsigned int cpu_idx, void *context, { assert(sec_state_is_valid(security_state)); - set_cpu_data_by_index(cpu_idx, cpu_context[security_state], context); + set_cpu_data_by_index(cpu_idx, + cpu_context[get_cpu_context_index(security_state)], + context); } diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h index c3f41179f..698e20876 100644 --- a/include/lib/el3_runtime/aarch64/context.h +++ b/include/lib/el3_runtime/aarch64/context.h @@ -405,13 +405,12 @@ DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); = (uint64_t) (val)) /* - * Top-level context structure which is used by EL3 firmware to - * preserve the state of a core at EL1 in one of the two security - * states and save enough EL3 meta data to be able to return to that - * EL and security state. The context management library will be used - * to ensure that SP_EL3 always points to an instance of this - * structure at exception entry and exit. Each instance will - * correspond to either the secure or the non-secure state. + * Top-level context structure which is used by EL3 firmware to preserve + * the state of a core at the next lower EL in a given security state and + * save enough EL3 meta data to be able to return to that EL and security + * state. The context management library will be used to ensure that + * SP_EL3 always points to an instance of this structure at exception + * entry and exit. */ typedef struct cpu_context { gp_regs_t gpregs_ctx; diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h index 3d57a5c59..2c7b61967 100644 --- a/include/lib/el3_runtime/cpu_data.h +++ b/include/lib/el3_runtime/cpu_data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,16 +19,25 @@ /* 8-bytes aligned size of psci_cpu_data structure */ #define PSCI_CPU_DATA_SIZE_ALIGNED ((PSCI_CPU_DATA_SIZE + 7) & ~7) +#if ENABLE_RME +/* Size of cpu_context array */ +#define CPU_DATA_CONTEXT_NUM 3 /* Offset of cpu_ops_ptr, size 8 bytes */ +#define CPU_DATA_CPU_OPS_PTR 0x18 +#else /* ENABLE_RME */ +#define CPU_DATA_CONTEXT_NUM 2 #define CPU_DATA_CPU_OPS_PTR 0x10 +#endif /* ENABLE_RME */ #if ENABLE_PAUTH /* 8-bytes aligned offset of apiakey[2], size 16 bytes */ -#define CPU_DATA_APIAKEY_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED) -#define CPU_DATA_CRASH_BUF_OFFSET (CPU_DATA_APIAKEY_OFFSET + 0x10) -#else -#define CPU_DATA_CRASH_BUF_OFFSET (0x18 + PSCI_CPU_DATA_SIZE_ALIGNED) -#endif /* ENABLE_PAUTH */ +#define CPU_DATA_APIAKEY_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \ + + CPU_DATA_CPU_OPS_PTR) +#define CPU_DATA_CRASH_BUF_OFFSET (0x10 + CPU_DATA_APIAKEY_OFFSET) +#else /* ENABLE_PAUTH */ +#define CPU_DATA_CRASH_BUF_OFFSET (0x8 + PSCI_CPU_DATA_SIZE_ALIGNED \ + + CPU_DATA_CPU_OPS_PTR) +#endif /* ENABLE_PAUTH */ /* need enough space in crash buffer to save 8 registers */ #define CPU_DATA_CRASH_BUF_SIZE 64 @@ -65,11 +74,14 @@ #ifndef __ASSEMBLER__ +#include +#include + #include #include #include + #include -#include /* Offsets for the cpu_data structure */ #define CPU_DATA_PSCI_LOCK_OFFSET __builtin_offsetof\ @@ -80,27 +92,34 @@ (cpu_data_t, platform_cpu_data) #endif +typedef enum context_pas { + CPU_CONTEXT_SECURE = 0, + CPU_CONTEXT_NS, +#if ENABLE_RME + CPU_CONTEXT_REALM, +#endif + CPU_CONTEXT_NUM +} context_pas_t; + /******************************************************************************* * Function & variable prototypes ******************************************************************************/ /******************************************************************************* * Cache of frequently used per-cpu data: - * Pointers to non-secure and secure security state contexts + * Pointers to non-secure, realm, and secure security state contexts * Address of the crash stack * It is aligned to the cache line boundary to allow efficient concurrent * manipulation of these pointers on different cpus * - * TODO: Add other commonly used variables to this (tf_issues#90) - * * The data structure and the _cpu_data accessors should not be used directly * by components that have per-cpu members. The member access macros should be * used for this. ******************************************************************************/ typedef struct cpu_data { #ifdef __aarch64__ - void *cpu_context[2]; -#endif + void *cpu_context[CPU_DATA_CONTEXT_NUM]; +#endif /* __aarch64__ */ uintptr_t cpu_ops_ptr; struct psci_cpu_data psci_svc_cpu_data; #if ENABLE_PAUTH @@ -122,6 +141,11 @@ typedef struct cpu_data { extern cpu_data_t percpu_data[PLATFORM_CORE_COUNT]; +#ifdef __aarch64__ +CASSERT(CPU_DATA_CONTEXT_NUM == CPU_CONTEXT_NUM, + assert_cpu_data_context_num_mismatch); +#endif + #if ENABLE_PAUTH CASSERT(CPU_DATA_APIAKEY_OFFSET == __builtin_offsetof (cpu_data_t, apiakey), @@ -160,6 +184,31 @@ static inline struct cpu_data *_cpu_data(void) struct cpu_data *_cpu_data(void); #endif +/* + * Returns the index of the cpu_context array for the given security state. + * All accesses to cpu_context should be through this helper to make sure + * an access is not out-of-bounds. The function assumes security_state is + * valid. + */ +static inline context_pas_t get_cpu_context_index(uint32_t security_state) +{ + if (security_state == SECURE) { + return CPU_CONTEXT_SECURE; + } else { +#if ENABLE_RME + if (security_state == NON_SECURE) { + return CPU_CONTEXT_NS; + } else { + assert(security_state == REALM); + return CPU_CONTEXT_REALM; + } +#else + assert(security_state == NON_SECURE); + return CPU_CONTEXT_NS; +#endif + } +} + /************************************************************************** * APIs for initialising and accessing per-cpu data *************************************************************************/ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 08022d4ad..0ec7e7e1c 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -93,24 +93,41 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) scr_el3 = read_scr(); scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT | SCR_ST_BIT | SCR_HCE_BIT); + +#if ENABLE_RME + /* When RME support is enabled, clear the NSE bit as well. */ + scr_el3 &= ~SCR_NSE_BIT; +#endif /* ENABLE_RME */ + /* * SCR_NS: Set the security state of the next EL. */ - if (security_state != SECURE) + if (security_state == NON_SECURE) { scr_el3 |= SCR_NS_BIT; + } + +#if ENABLE_RME + /* Check for realm state if RME support enabled. */ + if (security_state == REALM) { + scr_el3 |= SCR_NS_BIT | SCR_NSE_BIT | SCR_EnSCXT_BIT; + } +#endif /* ENABLE_RME */ + /* * SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next * Exception level as specified by SPSR. */ - if (GET_RW(ep->spsr) == MODE_RW_64) + if (GET_RW(ep->spsr) == MODE_RW_64) { scr_el3 |= SCR_RW_BIT; + } /* * SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical * Secure timer registers to EL3, from AArch64 state only, if specified * by the entrypoint attributes. */ - if (EP_GET_ST(ep->h.attr) != 0U) + if (EP_GET_ST(ep->h.attr) != 0U) { scr_el3 |= SCR_ST_BIT; + } /* * If FEAT_HCX is enabled, enable access to HCRX_EL2 by setting @@ -152,8 +169,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * If the Secure world wants to use pointer authentication, * CTX_INCLUDE_PAUTH_REGS must be set to 1. */ - if (security_state == NON_SECURE) + if (security_state == NON_SECURE) { scr_el3 |= SCR_API_BIT | SCR_APK_BIT; + } #endif /* !CTX_INCLUDE_PAUTH_REGS */ #if !CTX_INCLUDE_MTE_REGS || ENABLE_ASSERTIONS @@ -188,8 +206,14 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) /* * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ routing as * indicated by the interrupt routing model for BL31. + * + * TODO: The interrupt routing model code is not updated for REALM + * state. Use the default values of IRQ = FIQ = 0 for REALM security + * state for now. */ - scr_el3 |= get_scr_el3_from_routing_model(security_state); + if (security_state != REALM) { + scr_el3 |= get_scr_el3_from_routing_model(security_state); + } #endif /* Save the initialized value of CPTR_EL3 register */ @@ -256,9 +280,9 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * required by PSCI specification) */ sctlr_elx = (EP_GET_EE(ep->h.attr) != 0U) ? SCTLR_EE_BIT : 0U; - if (GET_RW(ep->spsr) == MODE_RW_64) + if (GET_RW(ep->spsr) == MODE_RW_64) { sctlr_elx |= SCTLR_EL1_RES1; - else { + } else { /* * If the target execution state is AArch32 then the following * fields need to be set. @@ -413,7 +437,8 @@ void cm_init_my_context(const entry_point_info_t *ep) } /******************************************************************************* - * Prepare the CPU system registers for first entry into secure or normal world + * Prepare the CPU system registers for first entry into realm, secure, or + * normal world. * * If execution is requested to EL2 or hyp mode, SCTLR_EL2 is initialized * If execution is requested to non-secure EL1 or svc mode, and the CPU supports @@ -497,7 +522,7 @@ void cm_prepare_el3_exit(uint32_t security_state) * architecturally UNKNOWN on reset and are set to zero * except for field(s) listed below. * - * CNTHCTL_EL2.EL1PCEN: Set to one to disable traps to + * CNTHCTL_EL2.EL1PTEN: Set to one to disable traps to * Hyp mode of Non-secure EL0 and EL1 accesses to the * physical timer registers. * @@ -645,10 +670,10 @@ void cm_el2_sysregs_context_save(uint32_t security_state) u_register_t scr_el3 = read_scr(); /* - * Always save the non-secure EL2 context, only save the + * Always save the non-secure and realm EL2 context, only save the * S-EL2 context if S-EL2 is enabled. */ - if ((security_state == NON_SECURE) || + if ((security_state != SECURE) || ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) { cpu_context_t *ctx; @@ -667,10 +692,10 @@ void cm_el2_sysregs_context_restore(uint32_t security_state) u_register_t scr_el3 = read_scr(); /* - * Always restore the non-secure EL2 context, only restore the + * Always restore the non-secure and realm EL2 context, only restore the * S-EL2 context if S-EL2 is enabled. */ - if ((security_state == NON_SECURE) || + if ((security_state != SECURE) || ((security_state == SECURE) && ((scr_el3 & SCR_EEL2_BIT) != 0U))) { cpu_context_t *ctx; -- cgit v1.2.3 From 434d0491c5504142e7077ff75471441e62855412 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Sun, 11 Jul 2021 17:25:48 -0500 Subject: refactor(makefile): remove BL prefixes in build macros The current Makefile assumes all TF-A binaries have BL prefixes (BL1, BL2, etc). Now that we have other binary names with FEAT_RME feature, remove this assumption. With this change, we need to pass the full name of a binary when using build macros. Signed-off-by: Zelalem Aweke Change-Id: I44e094b2366aa526f807d92dffa709390d14d145 --- Makefile | 14 ++--- make_helpers/build_macros.mk | 84 ++++++++++++++-------------- plat/marvell/armada/a8k/common/a8k_common.mk | 2 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 59d14ba02..d6e99f338 100644 --- a/Makefile +++ b/Makefile @@ -1148,7 +1148,7 @@ $(eval $(call MAKE_LIB,c)) # Expand build macros for the different images ifeq (${NEED_BL1},yes) -$(eval $(call MAKE_BL,1)) +$(eval $(call MAKE_BL,bl1)) endif ifeq (${NEED_BL2},yes) @@ -1157,7 +1157,7 @@ FIP_BL2_ARGS := tb-fw endif $(if ${BL2}, $(eval $(call TOOL_ADD_IMG,bl2,--${FIP_BL2_ARGS})),\ - $(eval $(call MAKE_BL,2,${FIP_BL2_ARGS}))) + $(eval $(call MAKE_BL,bl2,${FIP_BL2_ARGS}))) endif ifeq (${NEED_SCP_BL2},yes) @@ -1170,10 +1170,10 @@ BL31_SOURCES += ${SPD_SOURCES} BL31_SOURCES := $(sort ${BL31_SOURCES}) ifneq (${DECRYPTION_SUPPORT},none) $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\ - $(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31)))) + $(eval $(call MAKE_BL,bl31,soc-fw,,$(ENCRYPT_BL31)))) else $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw)),\ - $(eval $(call MAKE_BL,31,soc-fw))) + $(eval $(call MAKE_BL,bl31,soc-fw))) endif endif @@ -1186,10 +1186,10 @@ BL32_SOURCES := $(sort ${BL32_SOURCES}) BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1)) ifneq (${DECRYPTION_SUPPORT},none) -$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw,,$(ENCRYPT_BL32))),\ +$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw,,$(ENCRYPT_BL32))),\ $(eval $(call TOOL_ADD_IMG,bl32,--tos-fw,,$(ENCRYPT_BL32)))) else -$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,32,tos-fw)),\ +$(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw)),\ $(eval $(call TOOL_ADD_IMG,bl32,--tos-fw))) endif endif @@ -1201,7 +1201,7 @@ endif ifeq (${NEED_BL2U},yes) $(if ${BL2U}, $(eval $(call TOOL_ADD_IMG,bl2u,--ap-fwu-cfg,FWU_)),\ - $(eval $(call MAKE_BL,2u,ap-fwu-cfg,FWU_))) + $(eval $(call MAKE_BL,bl2u,ap-fwu-cfg,FWU_))) endif # Expand build macros for the different images diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 86550288c..12aaee684 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -98,41 +98,41 @@ $(if $(word $(2), $($(1))),\ endef # IMG_LINKERFILE defines the linker script corresponding to a BL stage -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage define IMG_LINKERFILE - ${BUILD_DIR}/bl$(1).ld + ${BUILD_DIR}/$(1).ld endef # IMG_MAPFILE defines the output file describing the memory map corresponding # to a BL stage -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage define IMG_MAPFILE - ${BUILD_DIR}/bl$(1).map + ${BUILD_DIR}/$(1).map endef # IMG_ELF defines the elf file corresponding to a BL stage -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage define IMG_ELF - ${BUILD_DIR}/bl$(1).elf + ${BUILD_DIR}/$(1).elf endef # IMG_DUMP defines the symbols dump file corresponding to a BL stage -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage define IMG_DUMP - ${BUILD_DIR}/bl$(1).dump + ${BUILD_DIR}/$(1).dump endef # IMG_BIN defines the default image file corresponding to a BL stage -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage define IMG_BIN - ${BUILD_PLAT}/bl$(1).bin + ${BUILD_PLAT}/$(1).bin endef # IMG_ENC_BIN defines the default encrypted image file corresponding to a # BL stage -# $(1) = BL stage (2, 30, 31, 32, 33) +# $(1) = BL stage define IMG_ENC_BIN - ${BUILD_PLAT}/bl$(1)_enc.bin + ${BUILD_PLAT}/$(1)_enc.bin endef # ENCRYPT_FW invokes enctool to encrypt firmware binary @@ -294,15 +294,15 @@ endef # MAKE_C builds a C source file and generates the dependency file # $(1) = output directory # $(2) = source file (%.c) -# $(3) = BL stage (1, 2, 2u, 31, 32) +# $(3) = BL stage define MAKE_C $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2)))) $(eval DEP := $(patsubst %.o,%.d,$(OBJ))) -$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) -$(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS)) +$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3))) +$(eval BL_CFLAGS := $($(call uppercase,$(3))_CFLAGS)) -$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs +$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs $$(ECHO) " CC $$<" $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CPPFLAGS) $(BL_CFLAGS) $(MAKE_DEP) -c $$< -o $$@ @@ -314,15 +314,15 @@ endef # MAKE_S builds an assembly source file and generates the dependency file # $(1) = output directory # $(2) = assembly file (%.S) -# $(3) = BL stage (1, 2, 2u, 31, 32) +# $(3) = BL stage define MAKE_S $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2)))) $(eval DEP := $(patsubst %.o,%.d,$(OBJ))) -$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) -$(eval BL_ASFLAGS := $(BL$(call uppercase,$(3))_ASFLAGS)) +$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3))) +$(eval BL_ASFLAGS := $($(call uppercase,$(3))_ASFLAGS)) -$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs +$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs $$(ECHO) " AS $$<" $$(Q)$$(AS) $$(ASFLAGS) $(BL_CPPFLAGS) $(BL_ASFLAGS) $(MAKE_DEP) -c $$< -o $$@ @@ -334,13 +334,13 @@ endef # MAKE_LD generate the linker script using the C preprocessor # $(1) = output linker script # $(2) = input template -# $(3) = BL stage (1, 2, 2u, 31, 32) +# $(3) = BL stage define MAKE_LD $(eval DEP := $(1).d) -$(eval BL_CPPFLAGS := $(BL$(call uppercase,$(3))_CPPFLAGS) -DIMAGE_BL$(call uppercase,$(3))) +$(eval BL_CPPFLAGS := $($(call uppercase,$(3))_CPPFLAGS) -DIMAGE_$(call uppercase,$(3))) -$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs +$(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | $(3)_dirs $$(ECHO) " PP $$<" $$(Q)$$(CPP) $$(CPPFLAGS) $(BL_CPPFLAGS) $(TF_CFLAGS_$(ARCH)) -P -x assembler-with-cpp -D__LINKER__ $(MAKE_DEP) -o $$@ $$< @@ -368,7 +368,7 @@ endef # MAKE_OBJS builds both C and assembly source files # $(1) = output directory # $(2) = list of source files (both C and assembly) -# $(3) = BL stage (1, 2, 2u, 31, 32) +# $(3) = BL stage define MAKE_OBJS $(eval C_OBJS := $(filter %.c,$(2))) $(eval REMAIN := $(filter-out %.c,$(2))) @@ -445,13 +445,13 @@ endef # MAKE_BL macro defines the targets and options to build each BL image. # Arguments: -# $(1) = BL stage (1, 2, 2u, 31, 32) +# $(1) = BL stage # $(2) = FIP command line option (if empty, image will not be included in the FIP) # $(3) = FIP prefix (optional) (if FWU_, target is fwu_fip instead of fip) # $(4) = BL encryption flag (optional) (0, 1) define MAKE_BL - $(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1)) - $(eval BL_SOURCES := $(BL$(call uppercase,$(1))_SOURCES)) + $(eval BUILD_DIR := ${BUILD_PLAT}/$(1)) + $(eval BL_SOURCES := $($(call uppercase,$(1))_SOURCES)) $(eval SOURCES := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)) $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES)))) $(eval LINKERFILE := $(call IMG_LINKERFILE,$(1))) @@ -460,8 +460,8 @@ define MAKE_BL $(eval DUMP := $(call IMG_DUMP,$(1))) $(eval BIN := $(call IMG_BIN,$(1))) $(eval ENC_BIN := $(call IMG_ENC_BIN,$(1))) - $(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE)) - $(eval BL_LIBS := $(BL$(call uppercase,$(1))_LIBS)) + $(eval BL_LINKERFILE := $($(call uppercase,$(1))_LINKERFILE)) + $(eval BL_LIBS := $($(call uppercase,$(1))_LIBS)) # We use sort only to get a list of unique object directory names. # ordering is not relevant but sort removes duplicates. $(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${LINKERFILE}))) @@ -475,21 +475,21 @@ $(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT})) $(eval $(foreach objd,${OBJ_DIRS},$(call MAKE_PREREQ_DIR,${objd},${BUILD_DIR}))) -.PHONY : bl${1}_dirs +.PHONY : ${1}_dirs # We use order-only prerequisites to ensure that directories are created, # but do not cause re-builds every time a file is written. -bl${1}_dirs: | ${OBJ_DIRS} +${1}_dirs: | ${OBJ_DIRS} $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1))) $(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1))) -$(eval BL_LDFLAGS := $(BL$(call uppercase,$(1))_LDFLAGS)) +$(eval BL_LDFLAGS := $($(call uppercase,$(1))_LDFLAGS)) ifeq ($(USE_ROMLIB),1) $(ELF): romlib.bin endif -$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs libraries $(BL_LIBS) +$(ELF): $(OBJS) $(LINKERFILE) | $(1)_dirs libraries $(BL_LIBS) $$(ECHO) " LD $$@" ifdef MAKE_BUILD_STRINGS $(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o) @@ -499,10 +499,10 @@ else $$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o endif ifneq ($(findstring armlink,$(notdir $(LD))),) - $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=bl${1}_entrypoint \ + $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) $(BL_LDFLAGS) --entry=${1}_entrypoint \ --predefine="-D__LINKER__=$(__LINKER__)" \ --predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \ - --map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \ + --map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/${1}.scat \ $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \ $(BUILD_DIR)/build_message.o $(OBJS) else ifneq ($(findstring gcc,$(notdir $(LD))),) @@ -531,21 +531,21 @@ $(BIN): $(ELF) @echo "Built $$@ successfully" @${ECHO_BLANK_LINE} -.PHONY: bl$(1) +.PHONY: $(1) ifeq ($(DISABLE_BIN_GENERATION),1) -bl$(1): $(ELF) $(DUMP) +$(1): $(ELF) $(DUMP) else -bl$(1): $(BIN) $(DUMP) +$(1): $(BIN) $(DUMP) endif -all: bl$(1) +all: $(1) ifeq ($(4),1) $(call ENCRYPT_FW,$(BIN),$(ENC_BIN)) -$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \ +$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(ENC_BIN),$(3), \ $(ENC_BIN))) else -$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,bl$(1),$(BIN),--$(2),$(BIN),$(3))) +$(if $(2),$(call TOOL_ADD_IMG_PAYLOAD,$(1),$(BIN),--$(2),$(BIN),$(3))) endif endef diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 30e6280e7..9474d085d 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -166,7 +166,7 @@ endif BLE_PATH ?= $(PLAT_COMMON_BASE)/ble include ${BLE_PATH}/ble.mk -$(eval $(call MAKE_BL,e)) +$(eval $(call MAKE_BL,ble)) clean realclean distclean: mrvl_clean -- cgit v1.2.3 From 5b18de09e80f87963df9a2e451c47e2321b8643a Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Sun, 11 Jul 2021 18:33:20 -0500 Subject: feat(rme): add ENABLE_RME build option and support for RMM image The changes include: - A new build option (ENABLE_RME) to enable FEAT_RME - New image called RMM. RMM is R-EL2 firmware that manages Realms. When building TF-A, a path to RMM image can be specified using the "RMM" build flag. If RMM image is not provided, TRP is built by default and used as RMM image. - Support for RMM image in fiptool Signed-off-by: Zelalem Aweke Change-Id: I017c23ef02e465a5198baafd665a60858ecd1b25 --- Makefile | 44 +++++++++++++++++++++++- bl31/bl31_main.c | 49 ++++++++++++++++++++++++--- docs/getting_started/build-options.rst | 4 +++ include/bl31/bl31.h | 3 +- include/common/bl_common.h | 4 ++- include/export/common/tbbr/tbbr_img_def_exp.h | 5 ++- include/tools_share/firmware_image_package.h | 2 ++ make_helpers/defaults.mk | 5 ++- services/std_svc/rmmd/rmmd.mk | 2 ++ tools/fiptool/tbbr_config.c | 7 +++- 10 files changed, 114 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index d6e99f338..ab61d1c94 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -129,6 +129,23 @@ else $(error Unknown BRANCH_PROTECTION value ${BRANCH_PROTECTION}) endif +# FEAT_RME +ifeq (${ENABLE_RME},1) +# RME doesn't support PIE +ifneq (${ENABLE_PIE},0) + $(error ENABLE_RME does not support PIE) +endif +# RME requires AARCH64 +ifneq (${ARCH},aarch64) + $(error ENABLE_RME requires AArch64) +endif +# RME requires el2 context to be saved for now. +CTX_INCLUDE_EL2_REGS := 1 +CTX_INCLUDE_AARCH32_REGS := 0 +ARM_ARCH_MAJOR := 8 +ARM_ARCH_MINOR := 6 +endif + # USE_SPINLOCK_CAS requires AArch64 build ifeq (${USE_SPINLOCK_CAS},1) ifneq (${ARCH},aarch64) @@ -558,6 +575,18 @@ ifneq (${SPD},none) # over the sources. endif +################################################################################ +# Include rmmd Makefile if RME is enabled +################################################################################ + +ifneq (${ENABLE_RME},0) +ifneq (${ARCH},aarch64) + $(error ENABLE_RME requires AArch64) +endif +include services/std_svc/rmmd/rmmd.mk +$(warning "RME is an experimental feature") +endif + ################################################################################ # Include the platform specific Makefile after the SPD Makefile (the platform # makefile may use all previous definitions in this file) @@ -926,6 +955,7 @@ $(eval $(call assert_booleans,\ ENABLE_PIE \ ENABLE_PMF \ ENABLE_PSCI_STAT \ + ENABLE_RME \ ENABLE_RUNTIME_INSTRUMENTATION \ ENABLE_SPE_FOR_LOWER_ELS \ ENABLE_SVE_FOR_NS \ @@ -1028,6 +1058,7 @@ $(eval $(call add_defines,\ ENABLE_PIE \ ENABLE_PMF \ ENABLE_PSCI_STAT \ + ENABLE_RME \ ENABLE_RUNTIME_INSTRUMENTATION \ ENABLE_SPE_FOR_LOWER_ELS \ ENABLE_SVE_FOR_NS \ @@ -1194,6 +1225,17 @@ $(if ${BUILD_BL32}, $(eval $(call MAKE_BL,bl32,tos-fw)),\ endif endif +# If RMM image is needed but RMM is not defined, Test Realm Payload (TRP) +# needs to be built from RMM_SOURCES. +ifeq (${NEED_RMM},yes) +# Sort RMM source files to remove duplicates +RMM_SOURCES := $(sort ${RMM_SOURCES}) +BUILD_RMM := $(if $(RMM),,$(if $(RMM_SOURCES),1)) + +$(if ${BUILD_RMM}, $(eval $(call MAKE_BL,rmm,rmm-fw)),\ + $(eval $(call TOOL_ADD_IMG,rmm,--rmm-fw))) +endif + # Add the BL33 image if required by the platform ifeq (${NEED_BL33},yes) $(eval $(call TOOL_ADD_IMG,bl33,--nt-fw)) diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c index f272af502..9ac10e240 100644 --- a/bl31/bl31_main.c +++ b/bl31/bl31_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -35,6 +35,13 @@ PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID, ******************************************************************************/ static int32_t (*bl32_init)(void); +/***************************************************************************** + * Function used to initialise RMM if RME is enabled + *****************************************************************************/ +#if ENABLE_RME +static int32_t (*rmm_init)(void); +#endif + /******************************************************************************* * Variable to indicate whether next image to execute after BL31 is BL33 * (non-secure & default) or BL32 (secure). @@ -139,12 +146,15 @@ void bl31_main(void) /* * All the cold boot actions on the primary cpu are done. We now need to - * decide which is the next image (BL32 or BL33) and how to execute it. + * decide which is the next image and how to execute it. * If the SPD runtime service is present, it would want to pass control * to BL32 first in S-EL1. In that case, SPD would have registered a * function to initialize bl32 where it takes responsibility of entering - * S-EL1 and returning control back to bl31_main. Once this is done we - * can prepare entry into BL33 as normal. + * S-EL1 and returning control back to bl31_main. Similarly, if RME is + * enabled and a function is registered to initialize RMM, control is + * transferred to RMM in R-EL2. After RMM initialization, control is + * returned back to bl31_main. Once this is done we can prepare entry + * into BL33 as normal. */ /* @@ -155,9 +165,27 @@ void bl31_main(void) int32_t rc = (*bl32_init)(); - if (rc == 0) + if (rc == 0) { WARN("BL31: BL32 initialization failed\n"); + } + } + + /* + * If RME is enabled and init hook is registered, initialize RMM + * in R-EL2. + */ +#if ENABLE_RME + if (rmm_init != NULL) { + INFO("BL31: Initializing RMM\n"); + + int32_t rc = (*rmm_init)(); + + if (rc == 0) { + WARN("BL31: RMM initialization failed\n"); + } } +#endif + /* * We are ready to enter the next EL. Prepare entry into the image * corresponding to the desired security state after the next ERET. @@ -236,3 +264,14 @@ void bl31_register_bl32_init(int32_t (*func)(void)) { bl32_init = func; } + +#if ENABLE_RME +/******************************************************************************* + * This function initializes the pointer to RMM init function. This is expected + * to be called by the RMMD after it finishes all its initialization + ******************************************************************************/ +void bl31_register_rmm_init(int32_t (*func)(void)) +{ + rmm_init = func; +} +#endif diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 7fe6ccd8a..1259881ed 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -271,6 +271,10 @@ Common build options be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in software. +- ``ENABLE_RME``: Boolean option to enable support for the ARMv9 Realm + Management Extension. Default value is 0. This is currently an experimental + feature. + - ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime instrumentation which injects timestamp collection points into TF-A to allow runtime performance to be measured. Currently, only PSCI is diff --git a/include/bl31/bl31.h b/include/bl31/bl31.h index 3deb0a51d..1d58ef968 100644 --- a/include/bl31/bl31.h +++ b/include/bl31/bl31.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,6 +19,7 @@ void bl31_set_next_image_type(uint32_t security_state); uint32_t bl31_get_next_image_type(void); void bl31_prepare_next_image_entry(void); void bl31_register_bl32_init(int32_t (*func)(void)); +void bl31_register_rmm_init(int32_t (*func)(void)); void bl31_warm_entrypoint(void); void bl31_main(void); void bl31_lib_init(void); diff --git a/include/common/bl_common.h b/include/common/bl_common.h index e33840c9d..8cb4990f0 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -126,6 +126,8 @@ IMPORT_SYM(uintptr_t, __BL31_START__, BL31_START); IMPORT_SYM(uintptr_t, __BL31_END__, BL31_END); #elif defined(IMAGE_BL32) IMPORT_SYM(uintptr_t, __BL32_END__, BL32_END); +#elif defined(IMAGE_RMM) +IMPORT_SYM(uintptr_t, __RMM_END__, RMM_END); #endif /* IMAGE_BLX */ /* The following symbols are only exported from the BL2 at EL3 linker script. */ diff --git a/include/export/common/tbbr/tbbr_img_def_exp.h b/include/export/common/tbbr/tbbr_img_def_exp.h index 2623c7599..98544c0ae 100644 --- a/include/export/common/tbbr/tbbr_img_def_exp.h +++ b/include/export/common/tbbr/tbbr_img_def_exp.h @@ -101,7 +101,10 @@ */ #define BKUP_FWU_METADATA_IMAGE_ID U(33) +/* Realm Monitor Manager (RMM) */ +#define RMM_IMAGE_ID U(34) + /* Max Images */ -#define MAX_IMAGE_IDS U(34) +#define MAX_IMAGE_IDS U(35) #endif /* ARM_TRUSTED_FIRMWARE_EXPORT_COMMON_TBBR_TBBR_IMG_DEF_EXP_H */ diff --git a/include/tools_share/firmware_image_package.h b/include/tools_share/firmware_image_package.h index dc65cc626..bd5b14b9d 100644 --- a/include/tools_share/firmware_image_package.h +++ b/include/tools_share/firmware_image_package.h @@ -38,6 +38,8 @@ {{0x8e, 0xa8, 0x7b, 0xb1}, {0xcf, 0xa2}, {0x3f, 0x4d}, 0x85, 0xfd, {0xe7, 0xbb, 0xa5, 0x02, 0x20, 0xd9} } #define UUID_NON_TRUSTED_FIRMWARE_BL33 \ {{0xd6, 0xd0, 0xee, 0xa7}, {0xfc, 0xea}, {0xd5, 0x4b}, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} } +#define UUID_REALM_MONITOR_MGMT_FIRMWARE \ + {{0x6c, 0x07, 0x62, 0xa6}, {0x12, 0xf2}, {0x4b, 0x56}, 0x92, 0xcb, {0xba, 0x8f, 0x63, 0x36, 0x06, 0xd9} } /* Key certificates */ #define UUID_ROT_KEY_CERT \ {{0x86, 0x2d, 0x1d, 0x72}, {0xf8, 0x60}, {0xe4, 0x11}, 0x92, 0x0b, {0x8b, 0xe7, 0x62, 0x16, 0x0f, 0x24} } diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 8b350db7b..819c53686 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2021, ARM Limited. All rights reserved. +# Copyright (c) 2016-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -105,6 +105,9 @@ ENABLE_PMF := 0 # Flag to enable PSCI STATs functionality ENABLE_PSCI_STAT := 0 +# Flag to enable Realm Management Extension (FEAT_RME) +ENABLE_RME := 0 + # Flag to enable runtime instrumentation using PMF ENABLE_RUNTIME_INSTRUMENTATION := 0 diff --git a/services/std_svc/rmmd/rmmd.mk b/services/std_svc/rmmd/rmmd.mk index b42568183..bac0a9f28 100644 --- a/services/std_svc/rmmd/rmmd.mk +++ b/services/std_svc/rmmd/rmmd.mk @@ -14,3 +14,5 @@ RMMD_SOURCES += $(addprefix services/std_svc/rmmd/, \ ${ARCH}/rmmd_helpers.S \ rmmd_main.c) +# Let the top-level Makefile know that we intend to include RMM image +NEED_RMM := yes diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c index c1e5217f0..4998bb2c2 100644 --- a/tools/fiptool/tbbr_config.c +++ b/tools/fiptool/tbbr_config.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -67,6 +67,11 @@ toc_entry_t toc_entries[] = { .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, .cmdline_name = "nt-fw" }, + { + .name = "Realm Monitor Management Firmware", + .uuid = UUID_REALM_MONITOR_MGMT_FIRMWARE, + .cmdline_name = "rmm-fw" + }, /* Dynamic Configs */ { .name = "FW_CONFIG", -- cgit v1.2.3 From 1839012d5b5d431f7ec307230eae9890a5fe7477 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Tue, 13 Jul 2021 14:05:20 -0500 Subject: feat(rme): add GPT Library This patch introduces the Granule Protection Table (GPT) library code. This implementation will be updated later to be more flexible, as the current implementation is very rigid. Signed-off-by: Zelalem Aweke Change-Id: I3af824a28c6e9a5d36459c0c51d2d9bebfba1505 --- bl2/bl2.mk | 4 +- bl31/aarch64/bl31_entrypoint.S | 10 +- bl31/bl31.mk | 5 +- include/lib/gpt/gpt.h | 86 +++++ include/lib/gpt/gpt_defs.h | 76 ++++ lib/gpt/gpt.mk | 8 + lib/gpt/gpt_core.c | 767 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 953 insertions(+), 3 deletions(-) create mode 100644 include/lib/gpt/gpt.h create mode 100644 include/lib/gpt/gpt_defs.h create mode 100644 lib/gpt/gpt.mk create mode 100644 lib/gpt/gpt_core.c diff --git a/bl2/bl2.mk b/bl2/bl2.mk index 54c73f506..fd8374795 100644 --- a/bl2/bl2.mk +++ b/bl2/bl2.mk @@ -17,10 +17,12 @@ endif ifeq (${ENABLE_RME},1) # Using RME, run BL2 at EL3 +include lib/gpt/gpt.mk + BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \ bl2/${ARCH}/bl2_el3_exceptions.S \ bl2/${ARCH}/bl2_run_next_image.S \ - + ${GPT_LIB_SRCS} BL2_LINKERFILE := bl2/bl2.ld.S else ifeq (${BL2_AT_EL3},0) diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 2d672dd12..2e9a39496 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -172,6 +172,14 @@ func bl31_warm_entrypoint _exception_vectors=runtime_exceptions \ _pie_fixup_size=0 +#if ENABLE_RME + /* + * Initialise and enable Granule Protection + * before enabling any stage of translation. + */ + bl gpt_enable +#endif + /* * We're about to enable MMU and participate in PSCI state coordination. * diff --git a/bl31/bl31.mk b/bl31/bl31.mk index ce0f69b7d..5927fb1c9 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -112,7 +112,10 @@ BL31_SOURCES += services/std_svc/pci_svc.c endif ifeq (${ENABLE_RME},1) -BL31_SOURCES += ${RMMD_SOURCES} +include lib/gpt/gpt.mk + +BL31_SOURCES += ${GPT_LIB_SRCS} \ + ${RMMD_SOURCES} endif BL31_LINKERFILE := bl31/bl31.ld.S diff --git a/include/lib/gpt/gpt.h b/include/lib/gpt/gpt.h new file mode 100644 index 000000000..89d30177d --- /dev/null +++ b/include/lib/gpt/gpt.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_H +#define GPT_H + +#include + +#include + +#include "gpt_defs.h" + +#define GPT_DESC_ATTRS(_type, _gpi) \ + ((((_type) & PAS_REG_DESC_TYPE_MASK) \ + << PAS_REG_DESC_TYPE_SHIFT) | \ + (((_gpi) & PAS_REG_GPI_MASK) \ + << PAS_REG_GPI_SHIFT)) + +/* + * Macro to create a GPT entry for this PAS range either as a L0 block + * descriptor or L1 table descriptor depending upon the size of the range. + */ +#define MAP_GPT_REGION(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_ANY, (_gpi)), \ + } + +/* + * Special macro to create a L1 table descriptor at L0 for a 1GB region as + * opposed to creating a block mapping by default. + */ +#define MAP_GPT_REGION_TBL(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, (_gpi)), \ + } + +/* + * Structure for specifying a Granule range and its properties + */ +typedef struct pas_region { + unsigned long long base_pa; /**< Base address for PAS. */ + size_t size; /**< Size of the PAS. */ + unsigned int attrs; /**< PAS GPI and entry type. */ +} pas_region_t; + +/* + * Structure to initialise the Granule Protection Tables. + */ +typedef struct gpt_init_params { + unsigned int pgs; /**< Address Width of Phisical Granule Size. */ + unsigned int pps; /**< Protected Physical Address Size. */ + unsigned int l0gptsz; /**< Granule size on L0 table entry. */ + pas_region_t *pas_regions; /**< PAS regions to protect. */ + unsigned int pas_count; /**< Number of PAS regions to initialise. */ + uintptr_t l0_mem_base; /**< L0 Table base address. */ + size_t l0_mem_size; /**< Size of memory reserved for L0 tables. */ + uintptr_t l1_mem_base; /**< L1 Table base address. */ + size_t l1_mem_size; /**< Size of memory reserved for L1 tables. */ +} gpt_init_params_t; + +/** @brief Initialise the Granule Protection tables. + */ +int gpt_init(gpt_init_params_t *params); + +/** @brief Enable the Granule Protection Checks. + */ +void gpt_enable(void); + +/** @brief Disable the Granule Protection Checks. + */ +void gpt_disable(void); + +/** @brief Transition a granule between security states. + */ +int gpt_transition_pas(uint64_t pa, + unsigned int src_sec_state, + unsigned int target_pas); + +#endif /* GPT_H */ diff --git a/include/lib/gpt/gpt_defs.h b/include/lib/gpt/gpt_defs.h new file mode 100644 index 000000000..6122a126f --- /dev/null +++ b/include/lib/gpt/gpt_defs.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_DEFS_H +#define GPT_DEFS_H + +#include +#include + +#include "gpt.h" + +/* GPI values */ +#define GPI_NO_ACCESS U(0x0) +#define GPI_SECURE U(0x8) +#define GPI_NS U(0x9) +#define GPI_ROOT U(0xa) +#define GPI_REALM U(0xb) +#define GPI_ANY U(0xf) +#define GPI_VAL_MASK ULL(0xf) + +/* GPT descriptor bit definitions */ +#define GPT_L1_INDEX_MASK ULL(0xf) +#define GPT_L1_INDEX_SHIFT ULL(0x0) + +#define GPT_TBL_DESC ULL(0x3) +#define GPT_BLK_DESC ULL(0x1) + +#define GPT_TBL_DESC_ADDR_SHIFT ULL(12) +#define GPT_TBL_DESC_ADDR_MASK (((ULL(1) << \ + (51 - GPT_TBL_DESC_ADDR_SHIFT)) - 1) \ + << GPT_TBL_DESC_ADDR_SHIFT) + +#define GPT_BLOCK_DESC_GPI_VAL_SHIFT ULL(4) + +/* Each descriptor is 8 bytes long. */ +#define GPT_DESC_SIZE ULL(8) + +#define PPS_MAX_VAL PSTCR_EL3_PPS_4PB +#define PPS_NUM_1GB_ENTRIES ULL(1024) +#define PGS_4K_1GB_L1_TABLE_SZ (U(2) << 17) + +/* 2 << LOG2_8K = Bytes in 8K */ +#define LOG2_8K U(13) + +#define GPT_L1_SIZE ULL(0x40000) /* 256K */ +#define SZ_1G (ULL(0x1) << 30) /* 1GB */ + +#define GPT_MIN_PGS_SHIFT U(12) /* 4K */ + +#define L1_GPT_INDEX_MASK U(0x3fffffff) +#define GPT_GRAN_DESC_NUM_GPIS U(4) + +#define PAS_REG_GPI_SHIFT U(0) +#define PAS_REG_GPI_MASK U(0xf) + +/* .attrs field definitions */ +#define PAS_REG_DESC_TYPE_ANY U(0) +#define PAS_REG_DESC_TYPE_BLK U(1) +#define PAS_REG_DESC_TYPE_TBL U(2) +#define PAS_REG_DESC_TYPE_SHIFT U(4) +#define PAS_REG_DESC_TYPE_MASK U(0x3) +#define PAS_REG_DESC_TYPE(_attrs) (((_attrs) \ + >> PAS_REG_DESC_TYPE_SHIFT) \ + & PAS_REG_DESC_TYPE_MASK) + +#define PAS_REG_GPI(_attrs) (((_attrs) \ + >> PAS_REG_GPI_SHIFT) \ + & PAS_REG_GPI_MASK) + +#define SZ_1G_MASK (SZ_1G - U(1)) +#define IS_1GB_ALIGNED(addr) (((addr) & SZ_1G_MASK) == U(0)) + +#endif /* GPT_DEFS */ diff --git a/lib/gpt/gpt.mk b/lib/gpt/gpt.mk new file mode 100644 index 000000000..611e50457 --- /dev/null +++ b/lib/gpt/gpt.mk @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +GPT_LIB_SRCS := $(addprefix lib/gpt/, \ + gpt_core.c) diff --git a/lib/gpt/gpt_core.c b/lib/gpt/gpt_core.c new file mode 100644 index 000000000..8a3afd2fa --- /dev/null +++ b/lib/gpt/gpt_core.c @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if !ENABLE_RME +#error "ENABLE_RME must be enabled to use the GPT library." +#endif + +typedef struct { + uintptr_t plat_gpt_l0_base; + uintptr_t plat_gpt_l1_base; + size_t plat_gpt_l0_size; + size_t plat_gpt_l1_size; + unsigned int plat_gpt_pps; + unsigned int plat_gpt_pgs; + unsigned int plat_gpt_l0gptsz; +} gpt_config_t; + +gpt_config_t gpt_config; + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) +/* Helper function that cleans the data cache only if it is enabled. */ +static inline + void gpt_clean_dcache_range(uintptr_t addr, size_t size) +{ + if ((read_sctlr_el3() & SCTLR_C_BIT) != 0U) { + clean_dcache_range(addr, size); + } +} + +/* Helper function that invalidates the data cache only if it is enabled. */ +static inline + void gpt_inv_dcache_range(uintptr_t addr, size_t size) +{ + if ((read_sctlr_el3() & SCTLR_C_BIT) != 0U) { + inv_dcache_range(addr, size); + } +} +#endif + +typedef struct l1_gpt_attr_desc { + size_t t_sz; /** Table size */ + size_t g_sz; /** Granularity size */ + unsigned int p_val; /** Associated P value */ +} l1_gpt_attr_desc_t; + +/* + * Lookup table to find out the size in bytes of the L1 tables as well + * as the index mask, given the Width of Physical Granule Size (PGS). + * L1 tables are indexed by PA[29:p+4], being 'p' the width in bits of the + * aforementioned Physical Granule Size. + */ +static const l1_gpt_attr_desc_t l1_gpt_attr_lookup[] = { + [GPCCR_PGS_4K] = {U(1) << U(17), /* 16384B x 64bit entry = 128KB */ + PAGE_SIZE_4KB, /* 4KB Granularity */ + U(12)}, + [GPCCR_PGS_64K] = {U(1) << U(13), /* Table size = 8KB */ + PAGE_SIZE_64KB, /* 64KB Granularity */ + U(16)}, + [GPCCR_PGS_16K] = {U(1) << U(15), /* Table size = 32KB */ + PAGE_SIZE_16KB, /* 16KB Granularity */ + U(14)} +}; + +typedef struct l0_gpt_attr_desc { + size_t sz; + unsigned int t_val_mask; +} l0_gpt_attr_desc_t; + +/* + * Lookup table to find out the size in bytes of the L0 table as well + * as the index mask, given the Protected Physical Address Size (PPS). + * L0 table is indexed by PA[t-1:30], being 't' the size in bits + * of the aforementioned Protected Physical Address Size. + */ +static const l0_gpt_attr_desc_t l0_gpt_attr_lookup[] = { + + [GPCCR_PPS_4GB] = {U(1) << U(5), /* 4 x 64 bit entry = 32 bytes */ + 0x3}, /* Bits[31:30] */ + + [GPCCR_PPS_64GB] = {U(1) << U(9), /* 512 bytes */ + 0x3f}, /* Bits[35:30] */ + + [GPCCR_PPS_1TB] = {U(1) << U(13), /* 8KB */ + 0x3ff}, /* Bits[39:30] */ + + [GPCCR_PPS_4TB] = {U(1) << U(15), /* 32KB */ + 0xfff}, /* Bits[41:30] */ + + [GPCCR_PPS_16TB] = {U(1) << U(17), /* 128KB */ + 0x3fff}, /* Bits[43:30] */ + + [GPCCR_PPS_256TB] = {U(1) << U(21), /* 2MB */ + 0x3ffff}, /* Bits[47:30] */ + + [GPCCR_PPS_4PB] = {U(1) << U(25), /* 32MB */ + 0x3fffff}, /* Bits[51:30] */ + +}; + +static unsigned int get_l1_gpt_index(unsigned int pgs, uintptr_t pa) +{ + unsigned int l1_gpt_arr_idx; + + /* + * Mask top 2 bits to obtain the 30 bits required to + * generate the L1 GPT index + */ + l1_gpt_arr_idx = (unsigned int)(pa & L1_GPT_INDEX_MASK); + + /* Shift by 'p' value + 4 to obtain the index */ + l1_gpt_arr_idx >>= (l1_gpt_attr_lookup[pgs].p_val + 4); + + return l1_gpt_arr_idx; +} + +unsigned int plat_is_my_cpu_primary(void); + +/* The granule partition tables can only be configured on BL2 */ +#ifdef IMAGE_BL2 + +/* Global to keep track of next available index in array of L1 GPTs */ +static unsigned int l1_gpt_mem_avlbl_index; + +static int validate_l0_gpt_params(gpt_init_params_t *params) +{ + /* Only 1GB of address space per L0 entry is allowed */ + if (params->l0gptsz != GPCCR_L0GPTSZ_30BITS) { + WARN("Invalid L0GPTSZ %u.\n", params->l0gptsz); + } + + /* Only 4K granule is supported for now */ + if (params->pgs != GPCCR_PGS_4K) { + WARN("Invalid GPT PGS %u.\n", params->pgs); + return -EINVAL; + } + + /* Only 4GB of protected physical address space is supported for now */ + if (params->pps != GPCCR_PPS_4GB) { + WARN("Invalid GPT PPS %u.\n", params->pps); + return -EINVAL; + } + + /* Check if GPT base address is aligned with the system granule */ + if (!IS_PAGE_ALIGNED(params->l0_mem_base)) { + ERROR("Unaligned L0 GPT base address.\n"); + return -EFAULT; + } + + /* Check if there is enough memory for L0 GPTs */ + if (params->l0_mem_size < l0_gpt_attr_lookup[params->pps].sz) { + ERROR("Inadequate memory for L0 GPTs. "); + ERROR("Expected 0x%lx bytes. Got 0x%lx bytes\n", + l0_gpt_attr_lookup[params->pps].sz, + params->l0_mem_size); + return -ENOMEM; + } + + return 0; +} + +/* + * A L1 GPT is required if any one of the following conditions is true: + * + * - The base address is not 1GB aligned + * - The size of the memory region is not a multiple of 1GB + * - A L1 GPT has been explicitly requested (attrs == PAS_REG_DESC_TYPE_TBL) + * + * This function: + * - iterates over all the PAS regions to determine whether they + * will need a 2 stage look up (and therefore a L1 GPT will be required) or + * if it would be enough with a single level lookup table. + * - Updates the attr field of the PAS regions. + * - Returns the total count of L1 tables needed. + * + * In the future wwe should validate that the PAS range does not exceed the + * configured PPS. (and maybe rename this function as it is validating PAS + * regions). + */ +static unsigned int update_gpt_type(pas_region_t *pas_regions, + unsigned int pas_region_cnt) +{ + unsigned int idx, cnt = 0U; + + for (idx = 0U; idx < pas_region_cnt; idx++) { + if (PAS_REG_DESC_TYPE(pas_regions[idx].attrs) == + PAS_REG_DESC_TYPE_TBL) { + cnt++; + continue; + } + if (!(IS_1GB_ALIGNED(pas_regions[idx].base_pa) && + IS_1GB_ALIGNED(pas_regions[idx].size))) { + + /* Current region will need L1 GPTs. */ + assert(PAS_REG_DESC_TYPE(pas_regions[idx].attrs) + == PAS_REG_DESC_TYPE_ANY); + + pas_regions[idx].attrs = + GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, + PAS_REG_GPI(pas_regions[idx].attrs)); + cnt++; + continue; + } + + /* The PAS can be mapped on a one stage lookup table */ + assert(PAS_REG_DESC_TYPE(pas_regions[idx].attrs) != + PAS_REG_DESC_TYPE_TBL); + + pas_regions[idx].attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_BLK, + PAS_REG_GPI(pas_regions[idx].attrs)); + } + + return cnt; +} + +static int validate_l1_gpt_params(gpt_init_params_t *params, + unsigned int l1_gpt_cnt) +{ + size_t l1_gpt_sz, l1_gpt_mem_sz; + + /* Check if the granularity is supported */ + assert(xlat_arch_is_granule_size_supported( + l1_gpt_attr_lookup[params->pgs].g_sz)); + + + /* Check if naturally aligned L1 GPTs can be created */ + l1_gpt_sz = l1_gpt_attr_lookup[params->pgs].g_sz; + if (params->l1_mem_base & (l1_gpt_sz - 1)) { + WARN("Unaligned L1 GPT base address.\n"); + return -EFAULT; + } + + /* Check if there is enough memory for L1 GPTs */ + l1_gpt_mem_sz = l1_gpt_cnt * l1_gpt_sz; + if (params->l1_mem_size < l1_gpt_mem_sz) { + WARN("Inadequate memory for L1 GPTs. "); + WARN("Expected 0x%lx bytes. Got 0x%lx bytes\n", + l1_gpt_mem_sz, params->l1_mem_size); + return -ENOMEM; + } + + INFO("Requested 0x%lx bytes for L1 GPTs.\n", l1_gpt_mem_sz); + return 0; +} + +/* + * Helper function to determine if the end physical address lies in the same GB + * as the current physical address. If true, the end physical address is + * returned else, the start address of the next GB is returned. + */ +static uintptr_t get_l1_gpt_end_pa(uintptr_t cur_pa, uintptr_t end_pa) +{ + uintptr_t cur_gb, end_gb; + + cur_gb = cur_pa >> ONE_GB_SHIFT; + end_gb = end_pa >> ONE_GB_SHIFT; + + assert(cur_gb <= end_gb); + + if (cur_gb == end_gb) { + return end_pa; + } + + return (cur_gb + 1) << ONE_GB_SHIFT; +} + +static void generate_l0_blk_desc(gpt_init_params_t *params, + unsigned int idx) +{ + uint64_t gpt_desc; + uintptr_t end_addr; + unsigned int end_idx, start_idx; + pas_region_t *pas = params->pas_regions + idx; + uint64_t *l0_gpt_arr = (uint64_t *)params->l0_mem_base; + + /* Create the GPT Block descriptor for this PAS region */ + gpt_desc = GPT_BLK_DESC; + gpt_desc |= PAS_REG_GPI(pas->attrs) + << GPT_BLOCK_DESC_GPI_VAL_SHIFT; + + /* Start index of this region in L0 GPTs */ + start_idx = pas->base_pa >> ONE_GB_SHIFT; + + /* + * Determine number of L0 GPT descriptors covered by + * this PAS region and use the count to populate these + * descriptors. + */ + end_addr = pas->base_pa + pas->size; + assert(end_addr \ + <= (ULL(l0_gpt_attr_lookup[params->pps].t_val_mask + 1)) << 30); + end_idx = end_addr >> ONE_GB_SHIFT; + + for (; start_idx < end_idx; start_idx++) { + l0_gpt_arr[start_idx] = gpt_desc; + INFO("L0 entry (BLOCK) index %u [%p]: GPI = 0x%llx (0x%llx)\n", + start_idx, &l0_gpt_arr[start_idx], + (gpt_desc >> GPT_BLOCK_DESC_GPI_VAL_SHIFT) & + GPT_L1_INDEX_MASK, l0_gpt_arr[start_idx]); + } +} + +static void generate_l0_tbl_desc(gpt_init_params_t *params, + unsigned int idx) +{ + uint64_t gpt_desc = 0U, *l1_gpt_arr; + uintptr_t start_pa, end_pa, cur_pa, next_pa; + unsigned int start_idx, l1_gpt_idx; + unsigned int p_val, gran_sz; + pas_region_t *pas = params->pas_regions + idx; + uint64_t *l0_gpt_base = (uint64_t *)params->l0_mem_base; + uint64_t *l1_gpt_base = (uint64_t *)params->l1_mem_base; + + start_pa = pas->base_pa; + end_pa = start_pa + pas->size; + p_val = l1_gpt_attr_lookup[params->pgs].p_val; + gran_sz = 1 << p_val; + + /* + * end_pa cannot be larger than the maximum protected physical memory. + */ + assert(((1ULL<<30) << l0_gpt_attr_lookup[params->pps].t_val_mask) + > end_pa); + + for (cur_pa = start_pa; cur_pa < end_pa;) { + /* + * Determine the PA range that will be covered + * in this loop iteration. + */ + next_pa = get_l1_gpt_end_pa(cur_pa, end_pa); + + INFO("PAS[%u]: start: 0x%lx, end: 0x%lx, next_pa: 0x%lx.\n", + idx, cur_pa, end_pa, next_pa); + + /* Index of this PA in L0 GPTs */ + start_idx = cur_pa >> ONE_GB_SHIFT; + + /* + * If cur_pa is on a 1GB boundary then determine + * the base address of next available L1 GPT + * memory region + */ + if (IS_1GB_ALIGNED(cur_pa)) { + l1_gpt_arr = (uint64_t *)((uint64_t)l1_gpt_base + + (l1_gpt_attr_lookup[params->pgs].t_sz * + l1_gpt_mem_avlbl_index)); + + assert(l1_gpt_arr < + (l1_gpt_base + params->l1_mem_size)); + + /* Create the L0 GPT descriptor for this PAS region */ + gpt_desc = GPT_TBL_DESC | + ((uintptr_t)l1_gpt_arr + & GPT_TBL_DESC_ADDR_MASK); + + l0_gpt_base[start_idx] = gpt_desc; + + /* + * Update index to point to next available L1 + * GPT memory region + */ + l1_gpt_mem_avlbl_index++; + } else { + /* Use the existing L1 GPT */ + l1_gpt_arr = (uint64_t *)(l0_gpt_base[start_idx] + & ~((1U<<12) - 1U)); + } + + INFO("L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%llx)\n", + start_idx, &l0_gpt_base[start_idx], + (unsigned long long)(l1_gpt_arr), + l0_gpt_base[start_idx]); + + /* + * Fill up L1 GPT entries between these two + * addresses. + */ + for (; cur_pa < next_pa; cur_pa += gran_sz) { + unsigned int gpi_idx, gpi_idx_shift; + + /* Obtain index of L1 GPT entry */ + l1_gpt_idx = get_l1_gpt_index(params->pgs, cur_pa); + + /* + * Obtain index of GPI in L1 GPT entry + * (i = PA[p_val+3:p_val]) + */ + gpi_idx = (cur_pa >> p_val) & GPT_L1_INDEX_MASK; + + /* + * Shift by index * 4 to reach correct + * GPI entry in L1 GPT descriptor. + * GPI = gpt_desc[(4*idx)+3:(4*idx)] + */ + gpi_idx_shift = gpi_idx << 2; + + gpt_desc = l1_gpt_arr[l1_gpt_idx]; + + /* Clear existing GPI encoding */ + gpt_desc &= ~(GPT_L1_INDEX_MASK << gpi_idx_shift); + + /* Set the GPI encoding */ + gpt_desc |= ((uint64_t)PAS_REG_GPI(pas->attrs) + << gpi_idx_shift); + + l1_gpt_arr[l1_gpt_idx] = gpt_desc; + + if (gpi_idx == 15U) { + VERBOSE("\tEntry %u [%p] = 0x%llx\n", + l1_gpt_idx, + &l1_gpt_arr[l1_gpt_idx], gpt_desc); + } + } + } +} + +static void create_gpt(gpt_init_params_t *params) +{ + unsigned int idx; + pas_region_t *pas_regions = params->pas_regions; + + INFO("pgs = 0x%x, pps = 0x%x, l0gptsz = 0x%x\n", + params->pgs, params->pps, params->l0gptsz); + INFO("pas_region_cnt = 0x%x L1 base = 0x%lx, L1 sz = 0x%lx\n", + params->pas_count, params->l1_mem_base, params->l1_mem_size); + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_inv_dcache_range(params->l0_mem_base, params->l0_mem_size); + gpt_inv_dcache_range(params->l1_mem_base, params->l1_mem_size); +#endif + + for (idx = 0U; idx < params->pas_count; idx++) { + + INFO("PAS[%u]: base 0x%llx, sz 0x%lx, GPI 0x%x, type 0x%x\n", + idx, pas_regions[idx].base_pa, pas_regions[idx].size, + PAS_REG_GPI(pas_regions[idx].attrs), + PAS_REG_DESC_TYPE(pas_regions[idx].attrs)); + + /* Check if a block or table descriptor is required */ + if (PAS_REG_DESC_TYPE(pas_regions[idx].attrs) == + PAS_REG_DESC_TYPE_BLK) { + generate_l0_blk_desc(params, idx); + + } else { + generate_l0_tbl_desc(params, idx); + } + } + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_clean_dcache_range(params->l0_mem_base, params->l0_mem_size); + gpt_clean_dcache_range(params->l1_mem_base, params->l1_mem_size); +#endif + + /* Make sure that all the entries are written to the memory. */ + dsbishst(); +} + +#endif /* IMAGE_BL2 */ + +int gpt_init(gpt_init_params_t *params) +{ +#ifdef IMAGE_BL2 + unsigned int l1_gpt_cnt; + int ret; +#endif + /* Validate arguments */ + assert(params != NULL); + assert(params->pgs <= GPCCR_PGS_16K); + assert(params->pps <= GPCCR_PPS_4PB); + assert(params->l0_mem_base != (uintptr_t)0); + assert(params->l0_mem_size > 0U); + assert(params->l1_mem_base != (uintptr_t)0); + assert(params->l1_mem_size > 0U); + +#ifdef IMAGE_BL2 + /* + * The Granule Protection Tables are initialised only in BL2. + * BL31 is not allowed to initialise them again in case + * these are modified by any other image loaded by BL2. + */ + assert(params->pas_regions != NULL); + assert(params->pas_count > 0U); + + ret = validate_l0_gpt_params(params); + if (ret < 0) { + + return ret; + } + + /* Check if L1 GPTs are required and how many. */ + l1_gpt_cnt = update_gpt_type(params->pas_regions, + params->pas_count); + INFO("%u L1 GPTs requested.\n", l1_gpt_cnt); + + if (l1_gpt_cnt > 0U) { + ret = validate_l1_gpt_params(params, l1_gpt_cnt); + if (ret < 0) { + return ret; + } + } + + create_gpt(params); +#else + /* If running in BL31, only primary CPU can initialise GPTs */ + assert(plat_is_my_cpu_primary() == 1U); + + /* + * If the primary CPU is calling this function from BL31 + * we expect that the tables are aready initialised from + * BL2 and GPCCR_EL3 is already configured with + * Granule Protection Check Enable bit set. + */ + assert((read_gpccr_el3() & GPCCR_GPC_BIT) != 0U); +#endif /* IMAGE_BL2 */ + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_inv_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); +#endif + gpt_config.plat_gpt_l0_base = params->l0_mem_base; + gpt_config.plat_gpt_l1_base = params->l1_mem_base; + gpt_config.plat_gpt_l0_size = params->l0_mem_size; + gpt_config.plat_gpt_l1_size = params->l1_mem_size; + + /* Backup the parameters used to configure GPCCR_EL3 on every PE. */ + gpt_config.plat_gpt_pgs = params->pgs; + gpt_config.plat_gpt_pps = params->pps; + gpt_config.plat_gpt_l0gptsz = params->l0gptsz; + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_clean_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); +#endif + + return 0; +} + +void gpt_enable(void) +{ + u_register_t gpccr_el3; + + /* Invalidate any stale TLB entries */ + tlbipaallos(); + +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_inv_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); +#endif + +#ifdef IMAGE_BL2 + /* + * Granule tables must be initialised before enabling + * granule protection. + */ + assert(gpt_config.plat_gpt_l0_base != (uintptr_t)NULL); +#endif + write_gptbr_el3(gpt_config.plat_gpt_l0_base >> GPTBR_BADDR_VAL_SHIFT); + + /* GPCCR_EL3.L0GPTSZ */ + gpccr_el3 = SET_GPCCR_L0GPTSZ(gpt_config.plat_gpt_l0gptsz); + + /* GPCCR_EL3.PPS */ + gpccr_el3 |= SET_GPCCR_PPS(gpt_config.plat_gpt_pps); + + /* GPCCR_EL3.PGS */ + gpccr_el3 |= SET_GPCCR_PGS(gpt_config.plat_gpt_pgs); + + /* Set shareability attribute to Outher Shareable */ + gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_OS); + + /* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */ + gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA); + gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA); + + /* Enable GPT */ + gpccr_el3 |= GPCCR_GPC_BIT; + + write_gpccr_el3(gpccr_el3); + dsbsy(); + + VERBOSE("Granule Protection Checks enabled\n"); +} + +void gpt_disable(void) +{ + u_register_t gpccr_el3 = read_gpccr_el3(); + + write_gpccr_el3(gpccr_el3 &= ~GPCCR_GPC_BIT); + dsbsy(); +} + +#ifdef IMAGE_BL31 + +/* + * Each L1 descriptor is protected by 1 spinlock. The number of descriptors is + * equal to the size of the total protected memory area divided by the size of + * protected memory area covered by each descriptor. + * + * The size of memory covered by each descriptor is the 'size of the granule' x + * 'number of granules' in a descriptor. The former is PLAT_ARM_GPT_PGS and + * latter is always 16. + */ +static spinlock_t gpt_lock; + +static unsigned int get_l0_gpt_index(unsigned int pps, uint64_t pa) +{ + unsigned int idx; + + /* Get the index into the L0 table */ + idx = pa >> ONE_GB_SHIFT; + + /* Check if the pa lies within the PPS */ + if (idx & ~(l0_gpt_attr_lookup[pps].t_val_mask)) { + WARN("Invalid address 0x%llx.\n", pa); + return -EINVAL; + } + + return idx; +} + +int gpt_transition_pas(uint64_t pa, + unsigned int src_sec_state, + unsigned int target_pas) +{ + int idx; + unsigned int idx_shift; + unsigned int gpi; + uint64_t gpt_l1_desc; + uint64_t *gpt_l1_addr, *gpt_addr; + + /* + * Check if caller is allowed to transition the granule's PAS. + * + * - Secure world caller can only request S <-> NS transitions on a + * granule that is already in either S or NS PAS. + * + * - Realm world caller can only request R <-> NS transitions on a + * granule that is already in either R or NS PAS. + */ + if (src_sec_state == SMC_FROM_REALM) { + if ((target_pas != GPI_REALM) && (target_pas != GPI_NS)) { + WARN("Invalid caller (%s) and PAS (%d) combination.\n", + "realm world", target_pas); + return -EINVAL; + } + } else if (src_sec_state == SMC_FROM_SECURE) { + if ((target_pas != GPI_SECURE) && (target_pas != GPI_NS)) { + WARN("Invalid caller (%s) and PAS (%d) combination.\n", + "secure world", target_pas); + return -EINVAL; + } + } else { + WARN("Invalid caller security state 0x%x\n", src_sec_state); + return -EINVAL; + } + + /* Obtain the L0 GPT address. */ + gpt_addr = (uint64_t *)gpt_config.plat_gpt_l0_base; + + /* Validate physical address and obtain index into L0 GPT table */ + idx = get_l0_gpt_index(gpt_config.plat_gpt_pps, pa); + if (idx < 0U) { + return idx; + } + + VERBOSE("PA 0x%llx, L0 base addr 0x%llx, L0 index %u\n", + pa, (uint64_t)gpt_addr, idx); + + /* Obtain the L0 descriptor */ + gpt_l1_desc = gpt_addr[idx]; + + /* + * Check if it is a table descriptor. Granule transition only applies to + * memory ranges for which L1 tables were created at boot time. So there + * is no possibility of splitting and coalescing tables. + */ + if ((gpt_l1_desc & GPT_L1_INDEX_MASK) != GPT_TBL_DESC) { + WARN("Invalid address 0x%llx.\n", pa); + return -EPERM; + } + + /* Obtain the L1 table address from L0 descriptor. */ + gpt_l1_addr = (uint64_t *)(gpt_l1_desc & ~(0xFFF)); + + /* Obtain the index into the L1 table */ + idx = get_l1_gpt_index(gpt_config.plat_gpt_pgs, pa); + + VERBOSE("L1 table base addr 0x%llx, L1 table index %u\n", (uint64_t)gpt_l1_addr, idx); + + /* Lock access to the granule */ + spin_lock(&gpt_lock); + + /* Obtain the L1 descriptor */ + gpt_l1_desc = gpt_l1_addr[idx]; + + /* Obtain the shift for GPI in L1 GPT entry */ + idx_shift = (pa >> 12) & GPT_L1_INDEX_MASK; + idx_shift <<= 2; + + /* Obtain the current GPI encoding for this PA */ + gpi = (gpt_l1_desc >> idx_shift) & GPT_L1_INDEX_MASK; + + if (src_sec_state == SMC_FROM_REALM) { + /* + * Realm world is only allowed to transition a NS or Realm world + * granule. + */ + if ((gpi != GPI_REALM) && (gpi != GPI_NS)) { + WARN("Invalid transition request from %s.\n", + "realm world"); + spin_unlock(&gpt_lock); + return -EPERM; + } + } else if (src_sec_state == SMC_FROM_SECURE) { + /* + * Secure world is only allowed to transition a NS or Secure world + * granule. + */ + if ((gpi != GPI_SECURE) && (gpi != GPI_NS)) { + WARN("Invalid transition request from %s.\n", + "secure world"); + spin_unlock(&gpt_lock); + return -EPERM; + } + } + /* We don't need an else here since we already handle that above. */ + + VERBOSE("L1 table desc 0x%llx before mod \n", gpt_l1_desc); + + /* Clear existing GPI encoding */ + gpt_l1_desc &= ~(GPT_L1_INDEX_MASK << idx_shift); + + /* Transition the granule to the new PAS */ + gpt_l1_desc |= ((uint64_t)target_pas << idx_shift); + + /* Update the L1 GPT entry */ + gpt_l1_addr[idx] = gpt_l1_desc; + + VERBOSE("L1 table desc 0x%llx after mod \n", gpt_l1_desc); + + /* Make sure change is propagated to other CPUs. */ +#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) + gpt_clean_dcache_range((uintptr_t)&gpt_addr[idx], sizeof(uint64_t)); +#endif + + gpt_tlbi_by_pa(pa, PAGE_SIZE_4KB); + + /* Make sure that all the entries are written to the memory. */ + dsbishst(); + + /* Unlock access to the granule */ + spin_unlock(&gpt_lock); + + return 0; +} + +#endif /* IMAGE_BL31 */ -- cgit v1.2.3 From 9d870b79c16ef09b0c4a9db18e071c2fa235d1ad Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Sun, 11 Jul 2021 18:39:39 -0500 Subject: feat(plat/fvp): add RMM image support for FVP platform This patch adds the necessary changes needed to build and load RMM image for the FVP platform. RMM image is loaded by BL2 after BL32 (if BL32 exists) and before BL33. Signed-off-by: Zelalem Aweke Change-Id: I1ac9eade84c2e35c7479a322ca1d090b4e626819 --- plat/arm/board/fvp/fvp_common.c | 9 ++++++ plat/arm/board/fvp/include/platform_def.h | 2 ++ plat/arm/board/fvp/platform.mk | 4 +++ plat/arm/common/aarch64/arm_bl2_mem_params_desc.c | 26 ++++++++++++++-- plat/arm/common/arm_bl31_setup.c | 37 ++++++++++++++++++----- plat/arm/common/fconf/arm_fconf_io.c | 6 ++++ 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 9d3c03133..1f9e4396b 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -191,6 +191,15 @@ const mmap_region_t plat_arm_mmap[] = { }; #endif +#ifdef IMAGE_RMM +const mmap_region_t plat_arm_mmap[] = { + V2M_MAP_IOFPGA, + MAP_DEVICE0, + MAP_DEVICE1, + {0} +}; +#endif + ARM_CASSERT_MMAP #if FVP_INTERCONNECT_DRIVER != FVP_CCN diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index a716546a4..6b084e491 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -185,6 +185,8 @@ # define PLATFORM_STACK_SIZE UL(0x800) #elif defined(IMAGE_BL32) # define PLATFORM_STACK_SIZE UL(0x440) +#elif defined(IMAGE_RMM) +# define PLATFORM_STACK_SIZE UL(0x440) #endif #define MAX_IO_DEVICES 3 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 73f09e50c..b37514626 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -186,6 +186,10 @@ ifeq (${COT_DESC_IN_DTB},1) BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c endif +ifeq (${ENABLE_RME},1) +BL2_SOURCES += plat/arm/board/fvp/aarch64/fvp_helpers.S +endif + ifeq (${BL2_AT_EL3},1) BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ plat/arm/board/fvp/fvp_bl2_el3_setup.c \ diff --git a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c index 6a8943d5d..0666e57fa 100644 --- a/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c +++ b/plat/arm/common/aarch64/arm_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -75,8 +75,10 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .image_info.image_base = BL31_BASE, .image_info.image_max_size = BL31_LIMIT - BL31_BASE, -# ifdef BL32_BASE +# if defined(BL32_BASE) .next_handoff_image_id = BL32_IMAGE_ID, +# elif ENABLE_RME + .next_handoff_image_id = RMM_IMAGE_ID, # else .next_handoff_image_id = BL33_IMAGE_ID, # endif @@ -99,6 +101,22 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING), .next_handoff_image_id = INVALID_IMAGE_ID, }, + +# if ENABLE_RME + /* Fill RMM related information */ + { + .image_id = RMM_IMAGE_ID, + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_2, entry_point_info_t, EP_REALM | EXECUTABLE), + .ep_info.pc = RMM_BASE, + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_2, image_info_t, 0), + .image_info.image_base = RMM_BASE, + .image_info.image_max_size = RMM_LIMIT - RMM_BASE, + .next_handoff_image_id = BL33_IMAGE_ID, + }, +# endif + # ifdef BL32_BASE /* Fill BL32 related information */ { @@ -113,7 +131,11 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { .image_info.image_base = BL32_BASE, .image_info.image_max_size = BL32_LIMIT - BL32_BASE, +# if ENABLE_RME + .next_handoff_image_id = RMM_IMAGE_ID, +# else .next_handoff_image_id = BL33_IMAGE_ID, +# endif }, /* diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index b819888d3..85a795360 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,9 @@ */ static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +#if ENABLE_RME +static entry_point_info_t rmm_image_ep_info; +#endif #if !RESET_TO_BL31 /* @@ -80,8 +83,18 @@ struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type) entry_point_info_t *next_image_info; assert(sec_state_is_valid(type)); - next_image_info = (type == NON_SECURE) - ? &bl33_image_ep_info : &bl32_image_ep_info; + if (type == NON_SECURE) { + next_image_info = &bl33_image_ep_info; + } +#if ENABLE_RME + else if (type == REALM) { + next_image_info = &rmm_image_ep_info; + } +#endif + else { + next_image_info = &bl32_image_ep_info; + } + /* * None of the images on the ARM development platforms can have 0x0 * as the entrypoint @@ -169,21 +182,31 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi bl_params_node_t *bl_params = params_from_bl2->head; /* - * Copy BL33 and BL32 (if present), entry point information. + * Copy BL33, BL32 and RMM (if present), entry point information. * They are stored in Secure RAM, in BL2's address space. */ while (bl_params != NULL) { - if (bl_params->image_id == BL32_IMAGE_ID) + if (bl_params->image_id == BL32_IMAGE_ID) { bl32_image_ep_info = *bl_params->ep_info; - - if (bl_params->image_id == BL33_IMAGE_ID) + } +#if ENABLE_RME + else if (bl_params->image_id == RMM_IMAGE_ID) { + rmm_image_ep_info = *bl_params->ep_info; + } +#endif + else if (bl_params->image_id == BL33_IMAGE_ID) { bl33_image_ep_info = *bl_params->ep_info; + } bl_params = bl_params->next_params_info; } if (bl33_image_ep_info.pc == 0U) panic(); +#if ENABLE_RME + if (rmm_image_ep_info.pc == 0U) + panic(); +#endif #endif /* RESET_TO_BL31 */ # if ARM_LINUX_KERNEL_AS_BL33 diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 86fd6d565..aea2f38d4 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -67,6 +67,7 @@ const io_uuid_spec_t arm_uuid_spec[MAX_NUMBER_IDS] = { [SOC_FW_CONFIG_ID] = {UUID_SOC_FW_CONFIG}, [TOS_FW_CONFIG_ID] = {UUID_TOS_FW_CONFIG}, [NT_FW_CONFIG_ID] = {UUID_NT_FW_CONFIG}, + [RMM_IMAGE_ID] = {UUID_REALM_MONITOR_MGMT_FIRMWARE}, #endif /* ARM_IO_IN_DTB */ #if TRUSTED_BOARD_BOOT [TRUSTED_BOOT_FW_CERT_ID] = {UUID_TRUSTED_BOOT_FW_CERT}, @@ -162,6 +163,11 @@ struct plat_io_policy policies[MAX_NUMBER_IDS] = { (uintptr_t)&arm_uuid_spec[BL33_IMAGE_ID], open_fip }, + [RMM_IMAGE_ID] = { + &fip_dev_handle, + (uintptr_t)&arm_uuid_spec[RMM_IMAGE_ID], + open_fip + }, [HW_CONFIG_ID] = { &fip_dev_handle, (uintptr_t)&arm_uuid_spec[HW_CONFIG_ID], -- cgit v1.2.3 From 4bb72c47dd78fb4119c0e41e283f295cc471d33b Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Mon, 12 Jul 2021 22:33:55 -0500 Subject: refactor(plat/arm): modify memory region attributes to account for FEAT_RME If FEAT_RME is enabled, EL3 runs in the Root world as opposed to Secure world. This patch changes EL3 memory region attributes for Arm platforms accordingly. Signed-off-by: Zelalem Aweke Change-Id: Ie176f8b440ff34330e4e44bd3bf8d9703b3892ff --- include/plat/arm/common/arm_def.h | 20 ++++++++++---------- plat/arm/common/arm_bl1_setup.c | 8 ++++---- plat/arm/common/arm_bl2_setup.c | 8 +++++++- plat/arm/common/arm_bl31_setup.c | 6 +++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 7cc215f22..173591f1b 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -209,7 +209,7 @@ #define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) + MT_DEVICE | MT_RW | EL3_PAS) #define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ ARM_NS_DRAM1_BASE, \ @@ -236,7 +236,7 @@ #define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \ ARM_EL3_TZC_DRAM1_BASE, \ ARM_EL3_TZC_DRAM1_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) #if defined(SPD_spmd) #define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \ @@ -255,7 +255,7 @@ #define ARM_MAP_BL1_RW MAP_REGION_FLAT( \ BL1_RW_BASE, \ BL1_RW_LIMIT - BL1_RW_BASE, \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) /* * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section @@ -265,35 +265,35 @@ #define ARM_MAP_BL_RO MAP_REGION_FLAT( \ BL_CODE_BASE, \ BL_CODE_END - BL_CODE_BASE, \ - MT_CODE | MT_SECURE), \ + MT_CODE | EL3_PAS), \ MAP_REGION_FLAT( \ BL_RO_DATA_BASE, \ BL_RO_DATA_END \ - BL_RO_DATA_BASE, \ - MT_RO_DATA | MT_SECURE) + MT_RO_DATA | EL3_PAS) #else #define ARM_MAP_BL_RO MAP_REGION_FLAT( \ BL_CODE_BASE, \ BL_CODE_END - BL_CODE_BASE, \ - MT_CODE | MT_SECURE) + MT_CODE | EL3_PAS) #endif #if USE_COHERENT_MEM #define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \ BL_COHERENT_RAM_BASE, \ BL_COHERENT_RAM_END \ - BL_COHERENT_RAM_BASE, \ - MT_DEVICE | MT_RW | MT_SECURE) + MT_DEVICE | MT_RW | EL3_PAS) #endif #if USE_ROMLIB #define ARM_MAP_ROMLIB_CODE MAP_REGION_FLAT( \ ROMLIB_RO_BASE, \ ROMLIB_RO_LIMIT - ROMLIB_RO_BASE,\ - MT_CODE | MT_SECURE) + MT_CODE | EL3_PAS) #define ARM_MAP_ROMLIB_DATA MAP_REGION_FLAT( \ ROMLIB_RW_BASE, \ ROMLIB_RW_END - ROMLIB_RW_BASE,\ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) #endif /* @@ -308,7 +308,7 @@ #define ARM_MAP_BL_CONFIG_REGION MAP_REGION_FLAT(ARM_BL_RAM_BASE, \ (ARM_FW_CONFIGS_LIMIT \ - ARM_BL_RAM_BASE), \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) /* * The max number of regions like RO(code), coherent and data required by diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index 872de3e3d..320bb8274 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -32,7 +32,7 @@ #define MAP_BL1_TOTAL MAP_REGION_FLAT( \ bl1_tzram_layout.total_base, \ bl1_tzram_layout.total_size, \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) /* * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section * otherwise one region is defined containing both @@ -41,17 +41,17 @@ #define MAP_BL1_RO MAP_REGION_FLAT( \ BL_CODE_BASE, \ BL1_CODE_END - BL_CODE_BASE, \ - MT_CODE | MT_SECURE), \ + MT_CODE | EL3_PAS), \ MAP_REGION_FLAT( \ BL1_RO_DATA_BASE, \ BL1_RO_DATA_END \ - BL_RO_DATA_BASE, \ - MT_RO_DATA | MT_SECURE) + MT_RO_DATA | EL3_PAS) #else #define MAP_BL1_RO MAP_REGION_FLAT( \ BL_CODE_BASE, \ BL1_CODE_END - BL_CODE_BASE, \ - MT_CODE | MT_SECURE) + MT_CODE | EL3_PAS) #endif /* Data structure which holds the extents of the trusted SRAM for BL1*/ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 5b26a1d3b..ae62016d0 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -45,11 +45,17 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); #pragma weak bl2_plat_get_hash #endif +#if ENABLE_RME +#define MAP_BL2_TOTAL MAP_REGION_FLAT( \ + bl2_tzram_layout.total_base, \ + bl2_tzram_layout.total_size, \ + MT_MEMORY | MT_RW | MT_ROOT) +#else #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ bl2_tzram_layout.total_base, \ bl2_tzram_layout.total_size, \ MT_MEMORY | MT_RW | MT_SECURE) - +#endif /* ENABLE_RME */ #pragma weak arm_bl2_plat_handle_post_image_load diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 85a795360..3286710de 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -46,7 +46,7 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #define MAP_BL31_TOTAL MAP_REGION_FLAT( \ BL31_START, \ BL31_END - BL31_START, \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) #if RECLAIM_INIT_CODE IMPORT_SYM(unsigned long, __INIT_CODE_START__, BL_INIT_CODE_BASE); IMPORT_SYM(unsigned long, __INIT_CODE_END__, BL_CODE_END_UNALIGNED); @@ -61,7 +61,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); BL_INIT_CODE_BASE, \ BL_INIT_CODE_END \ - BL_INIT_CODE_BASE, \ - MT_CODE | MT_SECURE) + MT_CODE | EL3_PAS) #endif #if SEPARATE_NOBITS_REGION @@ -69,7 +69,7 @@ IMPORT_SYM(unsigned long, __STACKS_END__, BL_STACKS_END_UNALIGNED); BL31_NOBITS_BASE, \ BL31_NOBITS_LIMIT \ - BL31_NOBITS_BASE, \ - MT_MEMORY | MT_RW | MT_SECURE) + MT_MEMORY | MT_RW | EL3_PAS) #endif /******************************************************************************* -- cgit v1.2.3 From c8720729726faffc39ec64f3a02440a48c8c305a Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Mon, 12 Jul 2021 23:41:05 -0500 Subject: feat(plat/fvp): add memory map for FVP platform for FEAT_RME When FEAT_RME is enabled, memory is divided into four Physical Address Spaces (PAS): Root, Realm, Secure and Non-secure. This patch introduces new carveouts for the Trusted SRAM and DRAM for the FVP platform accordingly. The following new regions are introduced with this change: ARM_MAP_L0_GPT_REGION: Trusted SRAM region used to store Level 0 Granule Protection Table (GPT). This region resides in the Root PAS. ARM_MAP_GPT_L1_DRAM: DRAM region used to store Level 1 GPT. It resides in the Root PAS. ARM_MAP_RMM_DRAM: DRAM region used to store RMM image. It resides in the Realm PAS. The L0 GPT is stored on Trusted SRAM next to firmware configuration memory. The DRAM carveout when RME is enable is modified as follow: -------------------- | | | AP TZC (~28MB) | -------------------- | | | REALM (32MB) | -------------------- | | | EL3 TZC (3MB) | -------------------- | L1 GPT + SCP TZC | | (~1MB) | 0xFFFF_FFFF -------------------- During initialization of the TrustZone controller, Root regions are configured as Secure regions. Then they are later reconfigured to Root upon GPT initialization. Signed-off-by: Zelalem Aweke Change-Id: If2e257141d51f51f715b70d4a06f18af53607254 --- include/plat/arm/common/arm_def.h | 125 +++++++++++++++++++++++++----- include/plat/arm/common/arm_pas_def.h | 90 +++++++++++++++++++++ include/plat/arm/common/plat_arm.h | 15 +++- plat/arm/board/fvp/fvp_common.c | 7 ++ plat/arm/board/fvp/include/platform_def.h | 30 +++++-- plat/arm/common/arm_bl2_setup.c | 3 + plat/arm/common/arm_bl31_setup.c | 3 + 7 files changed, 246 insertions(+), 27 deletions(-) create mode 100644 include/plat/arm/common/arm_pas_def.h diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 173591f1b..a8b5d26df 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -74,38 +74,84 @@ ARM_SHARED_RAM_SIZE) /* - * The top 16MB of DRAM1 is configured as secure access only using the TZC + * The top 16MB (or 64MB if RME is enabled) of DRAM1 is configured as + * follows: * - SCP TZC DRAM: If present, DRAM reserved for SCP use + * - L1 GPT DRAM: Reserved for L1 GPT if RME is enabled + * - REALM DRAM: Reserved for Realm world if RME is enabled * - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use + * + * RME enabled(64MB) RME not enabled(16MB) + * -------------------- ------------------- + * | | | | + * | AP TZC (~28MB) | | AP TZC (~14MB) | + * -------------------- ------------------- + * | | | | + * | REALM (32MB) | | EL3 TZC (2MB) | + * -------------------- ------------------- + * | | | | + * | EL3 TZC (3MB) | | SCP TZC | + * -------------------- 0xFFFF_FFFF------------------- + * | L1 GPT + SCP TZC | + * | (~1MB) | + * 0xFFFF_FFFF -------------------- + */ +#if ENABLE_RME +#define ARM_TZC_DRAM1_SIZE UL(0x04000000) /* 64MB */ +/* + * Define a region within the TZC secured DRAM for use by EL3 runtime + * firmware. This region is meant to be NOLOAD and will not be zero + * initialized. Data sections with the attribute `arm_el3_tzc_dram` will be + * placed here. 3MB region is reserved if RME is enabled, 2MB otherwise. */ -#define ARM_TZC_DRAM1_SIZE UL(0x01000000) +#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */ +#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */ +#define ARM_REALM_SIZE UL(0x02000000) /* 32MB */ +#else +#define ARM_TZC_DRAM1_SIZE UL(0x01000000) /* 16MB */ +#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2MB */ +#define ARM_L1_GPT_SIZE UL(0) +#define ARM_REALM_SIZE UL(0) +#endif /* ENABLE_RME */ #define ARM_SCP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \ - ARM_DRAM1_SIZE - \ - ARM_SCP_TZC_DRAM1_SIZE) + ARM_DRAM1_SIZE - \ + (ARM_SCP_TZC_DRAM1_SIZE + \ + ARM_L1_GPT_SIZE)) #define ARM_SCP_TZC_DRAM1_SIZE PLAT_ARM_SCP_TZC_DRAM1_SIZE #define ARM_SCP_TZC_DRAM1_END (ARM_SCP_TZC_DRAM1_BASE + \ - ARM_SCP_TZC_DRAM1_SIZE - 1U) - -/* - * Define a 2MB region within the TZC secured DRAM for use by EL3 runtime - * firmware. This region is meant to be NOLOAD and will not be zero - * initialized. Data sections with the attribute `arm_el3_tzc_dram` will be - * placed here. - */ -#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - ARM_EL3_TZC_DRAM1_SIZE) -#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00200000) /* 2 MB */ + ARM_SCP_TZC_DRAM1_SIZE - 1U) +#if ENABLE_RME +#define ARM_L1_GPT_ADDR_BASE (ARM_DRAM1_BASE + \ + ARM_DRAM1_SIZE - \ + ARM_L1_GPT_SIZE) +#define ARM_L1_GPT_END (ARM_L1_GPT_ADDR_BASE + \ + ARM_L1_GPT_SIZE - 1U) + +#define ARM_REALM_BASE (ARM_DRAM1_BASE + \ + ARM_DRAM1_SIZE - \ + (ARM_SCP_TZC_DRAM1_SIZE + \ + ARM_EL3_TZC_DRAM1_SIZE + \ + ARM_REALM_SIZE + \ + ARM_L1_GPT_SIZE)) +#define ARM_REALM_END (ARM_REALM_BASE + ARM_REALM_SIZE - 1U) +#endif /* ENABLE_RME */ + +#define ARM_EL3_TZC_DRAM1_BASE (ARM_SCP_TZC_DRAM1_BASE - \ + ARM_EL3_TZC_DRAM1_SIZE) #define ARM_EL3_TZC_DRAM1_END (ARM_EL3_TZC_DRAM1_BASE + \ ARM_EL3_TZC_DRAM1_SIZE - 1U) #define ARM_AP_TZC_DRAM1_BASE (ARM_DRAM1_BASE + \ - ARM_DRAM1_SIZE - \ - ARM_TZC_DRAM1_SIZE) + ARM_DRAM1_SIZE - \ + ARM_TZC_DRAM1_SIZE) #define ARM_AP_TZC_DRAM1_SIZE (ARM_TZC_DRAM1_SIZE - \ - (ARM_SCP_TZC_DRAM1_SIZE + \ - ARM_EL3_TZC_DRAM1_SIZE)) + (ARM_SCP_TZC_DRAM1_SIZE + \ + ARM_EL3_TZC_DRAM1_SIZE + \ + ARM_REALM_SIZE + \ + ARM_L1_GPT_SIZE)) #define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \ - ARM_AP_TZC_DRAM1_SIZE - 1U) + ARM_AP_TZC_DRAM1_SIZE - 1U) /* Define the Access permissions for Secure peripherals to NS_DRAM */ #if ARM_CRYPTOCELL_INTEG @@ -245,6 +291,19 @@ MT_MEMORY | MT_RW | MT_SECURE) #endif +#if ENABLE_RME +#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \ + PLAT_ARM_RMM_BASE, \ + PLAT_ARM_RMM_SIZE, \ + MT_MEMORY | MT_RW | MT_REALM) + + +#define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \ + ARM_L1_GPT_ADDR_BASE, \ + ARM_L1_GPT_SIZE, \ + MT_MEMORY | MT_RW | EL3_PAS) + +#endif /* ENABLE_RME */ /* * Mapping for the BL1 RW region. This mapping is needed by BL2 in order to @@ -309,6 +368,14 @@ (ARM_FW_CONFIGS_LIMIT \ - ARM_BL_RAM_BASE), \ MT_MEMORY | MT_RW | EL3_PAS) +/* + * Map L0_GPT with read and write permissions + */ +#if ENABLE_RME +#define ARM_MAP_L0_GPT_REGION MAP_REGION_FLAT(ARM_L0_GPT_ADDR_BASE, \ + ARM_L0_GPT_SIZE, \ + MT_MEMORY | MT_RW | MT_ROOT) +#endif /* * The max number of regions like RO(code), coherent and data required by @@ -409,6 +476,18 @@ */ #define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE * 2)) +#if ENABLE_RME +/* + * Store the L0 GPT on Trusted SRAM next to firmware + * configuration memory, 4KB aligned. + */ +#define ARM_L0_GPT_SIZE (PAGE_SIZE) +#define ARM_L0_GPT_ADDR_BASE (ARM_FW_CONFIGS_LIMIT) +#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_ADDR_BASE + ARM_L0_GPT_SIZE) +#else +#define ARM_L0_GPT_SIZE U(0) +#endif + /******************************************************************************* * BL1 specific defines. * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of @@ -501,6 +580,14 @@ #endif #endif +/****************************************************************************** + * RMM specific defines + *****************************************************************************/ +#if ENABLE_RME +#define RMM_BASE (ARM_REALM_BASE) +#define RMM_LIMIT (RMM_BASE + ARM_REALM_SIZE) +#endif + #if !defined(__aarch64__) || JUNO_AARCH32_EL3_RUNTIME /******************************************************************************* * BL32 specific defines for EL3 runtime in AArch32 mode diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h new file mode 100644 index 000000000..a8ebee3f1 --- /dev/null +++ b/include/plat/arm/common/arm_pas_def.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef ARM_PAS_DEF_H +#define ARM_PAS_DEF_H + +#include + +/***************************************************************************** + * PAS regions used to initialize the Granule Protection Table (GPT) + ****************************************************************************/ + +/* + * The PA space is initially mapped in the GPT as follows: + * + * ============================================================================ + * Base Addr| Size |L? GPT|PAS |Content |Comment + * ============================================================================ + * 0GB | 1GB |L0 GPT|ANY |TBROM (EL3 code) |Fixed mapping + * | | | |TSRAM (EL3 data) | + * | | | |IO (incl.UARTs & GIC) | + * ---------------------------------------------------------------------------- + * 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping + * ---------------------------------------------------------------------------- + * 2GB | 1GB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip + * ---------------------------------------------------------------------------- + * 3GB |1GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip + * ---------------------------------------------------------------------------- + * 4GB-64MB |64MB-32MB | | | | + * | -4MB |L1 GPT|SECURE|DRAM TZC |Use T.Descrip + * ---------------------------------------------------------------------------- + * 4GB-32MB | | | | | + * -3MB-1MB |32MB |L1 GPT|REALM |RMM |Use T.Descrip + * ---------------------------------------------------------------------------- + * 4GB-3MB | | | | | + * -1MB |3MB |L1 GPT|ROOT |EL3 DRAM data |Use T.Descrip + * ---------------------------------------------------------------------------- + * 4GB-1MB |1MB |L1 GPT|ROOT |DRAM (L1 GPTs, SCP TZC) |Fixed mapping + * ============================================================================ + * + * - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section. + * - ~1MB of L1 GPTs reside at the top of DRAM1 (TZC area). + * - The first 1GB region has GPI_ANY and, therefore, is not protected by + * the GPT. + * - The DRAM TZC area is split into three regions: the L1 GPT region and + * 3MB of region below that are defined as GPI_ROOT, 32MB Realm region + * below that is defined as GPI_REALM and the rest of it is defined as + * GPI_SECURE. + */ + +/* TODO: This might not be the best way to map the PAS */ + +/* Device memory 0 to 2GB */ +#define ARM_PAS_1_BASE (U(0)) +#define ARM_PAS_1_SIZE ((ULL(1)<<31)) /* 2GB */ + +/* NS memory 2GB to (end - 64MB) */ +#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE) +#define ARM_PAS_2_SIZE (ARM_NS_DRAM1_SIZE) + +/* Secure TZC region */ +#define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE) +#define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE) + +#define ARM_PAS_GPI_ANY MAP_GPT_REGION(ARM_PAS_1_BASE, \ + ARM_PAS_1_SIZE, \ + GPI_ANY) +#define ARM_PAS_KERNEL MAP_GPT_REGION_TBL(ARM_PAS_2_BASE, \ + ARM_PAS_2_SIZE, \ + GPI_NS) + +#define ARM_PAS_TZC MAP_GPT_REGION_TBL(ARM_PAS_3_BASE, \ + ARM_PAS_3_SIZE, \ + GPI_SECURE) + +#define ARM_PAS_REALM MAP_GPT_REGION_TBL(ARM_REALM_BASE, \ + ARM_REALM_SIZE, \ + GPI_REALM) + +#define ARM_PAS_EL3_DRAM MAP_GPT_REGION_TBL(ARM_EL3_TZC_DRAM1_BASE, \ + ARM_EL3_TZC_DRAM1_SIZE, \ + GPI_ROOT) + +#define ARM_PAS_GPTS MAP_GPT_REGION_TBL(ARM_L1_GPT_ADDR_BASE, \ + ARM_L1_GPT_SIZE, \ + GPI_ROOT) + +#endif /* ARM_PAS_DEF_H */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 0a19d8b36..1500ed379 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -41,7 +41,7 @@ typedef struct arm_tzc_regions_info { ******************************************************************************/ #if SPM_MM #define ARM_TZC_REGIONS_DEF \ - {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \ + {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\ TZC_REGION_S_RDWR, 0}, \ {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ PLAT_ARM_TZC_NS_DEV_ACCESS}, \ @@ -51,9 +51,20 @@ typedef struct arm_tzc_regions_info { PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \ PLAT_ARM_TZC_NS_DEV_ACCESS} +#elif ENABLE_RME +#define ARM_TZC_REGIONS_DEF \ + {ARM_AP_TZC_DRAM1_BASE, ARM_AP_TZC_DRAM1_END, TZC_REGION_S_RDWR, 0},\ + {ARM_EL3_TZC_DRAM1_BASE, ARM_L1_GPT_END, TZC_REGION_S_RDWR, 0}, \ + {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {ARM_REALM_BASE, ARM_REALM_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS} + #else #define ARM_TZC_REGIONS_DEF \ - {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \ + {ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END + ARM_L1_GPT_SIZE,\ TZC_REGION_S_RDWR, 0}, \ {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ PLAT_ARM_TZC_NS_DEV_ACCESS}, \ diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 1f9e4396b..e7a28ac35 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -107,6 +107,10 @@ const mmap_region_t plat_arm_mmap[] = { #if defined(SPD_spmd) ARM_MAP_TRUSTED_DRAM, #endif +#if ENABLE_RME + ARM_MAP_RMM_DRAM, + ARM_MAP_GPT_L1_DRAM, +#endif /* ENABLE_RME */ #ifdef SPD_tspd ARM_MAP_TSP_SEC_MEM, #endif @@ -159,6 +163,9 @@ const mmap_region_t plat_arm_mmap[] = { #endif /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ ARM_DTB_DRAM_NS, +#if ENABLE_RME + ARM_MAP_GPT_L1_DRAM, +#endif {0} }; diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 6b084e491..6e72b5999 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -43,6 +43,11 @@ #define PLAT_ARM_TRUSTED_DRAM_BASE UL(0x06000000) #define PLAT_ARM_TRUSTED_DRAM_SIZE UL(0x02000000) /* 32 MB */ +#if ENABLE_RME +#define PLAT_ARM_RMM_BASE (RMM_BASE) +#define PLAT_ARM_RMM_SIZE (RMM_LIMIT - RMM_BASE) +#endif + /* * Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to * max size of BL32 image. @@ -80,15 +85,27 @@ #if defined(IMAGE_BL31) # if SPM_MM # define PLAT_ARM_MMAP_ENTRIES 10 -# define MAX_XLAT_TABLES 9 +# if ENABLE_RME +# define MAX_XLAT_TABLES 10 +# else +# define MAX_XLAT_TABLES 9 +# endif # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS -# define MAX_XLAT_TABLES 8 +# if ENABLE_RME +# define MAX_XLAT_TABLES 9 +# else +# define MAX_XLAT_TABLES 8 +# endif # else -# define MAX_XLAT_TABLES 7 +# if ENABLE_RME +# define MAX_XLAT_TABLES 8 +# else +# define MAX_XLAT_TABLES 7 +# endif # endif # endif #elif defined(IMAGE_BL32) @@ -137,16 +154,17 @@ #endif #if RESET_TO_BL31 -/* Size of Trusted SRAM - the first 4KB of shared memory */ +/* Size of Trusted SRAM - the first 4KB of shared memory - GPT L0 Tables */ #define PLAT_ARM_MAX_BL31_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ - ARM_SHARED_RAM_SIZE) + ARM_SHARED_RAM_SIZE - \ + ARM_L0_GPT_SIZE) #else /* * Since BL31 NOBITS overlays BL2 and BL1-RW, PLAT_ARM_MAX_BL31_SIZE is * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3D000) +#define PLAT_ARM_MAX_BL31_SIZE (UL(0x3D000) - ARM_L0_GPT_SIZE) #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index ae62016d0..758a061b8 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -149,6 +149,9 @@ void arm_bl2_plat_arch_setup(void) ARM_MAP_BL_COHERENT_RAM, #endif ARM_MAP_BL_CONFIG_REGION, +#if ENABLE_RME + ARM_MAP_L0_GPT_REGION, +#endif {0} }; diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 3286710de..d2bacd3fa 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -378,6 +378,9 @@ void __init arm_bl31_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL31_TOTAL, +#if ENABLE_RME + ARM_MAP_L0_GPT_REGION, +#endif #if RECLAIM_INIT_CODE MAP_BL_INIT_CODE, #endif -- cgit v1.2.3 From deb4b3a63e3a52f2e9823865a1932f6289ccb7ac Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Tue, 13 Jul 2021 17:19:54 -0500 Subject: feat(plat/arm): add GPT initialization code for Arm platforms When RME is enabled, during configuration of the TrustZone controller, Root regions are initially configured as Secure regions, and Realm regions as Non-secure regions. Then later these regions are configured as Root and Realm regions respectively in the GPT. According to the RME architecture reference manual, Root firmware must ensure that Granule Protection Check is enabled before enabling any stage of translation. Therefore initializations are done as follows when RME is enabled : Initialize/enable the TrustZone controller (plat_arm_security_setup) --> Initialize/enable GPC (arm_bl2_plat_gpt_setup) --> enable MMU (enable_mmu_el3) Signed-off-by: Zelalem Aweke Change-Id: I91094e8259079437bee02de1f65edb9ad51e43cf --- include/plat/arm/common/arm_pas_def.h | 5 +++ plat/arm/common/arm_bl2_setup.c | 60 +++++++++++++++++++++++++++++++++-- plat/arm/common/arm_bl31_setup.c | 24 ++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h index a8ebee3f1..d268ce613 100644 --- a/include/plat/arm/common/arm_pas_def.h +++ b/include/plat/arm/common/arm_pas_def.h @@ -87,4 +87,9 @@ ARM_L1_GPT_SIZE, \ GPI_ROOT) +/* GPT Configuration options */ +#define PLATFORM_PGS GPCCR_PGS_4K +#define PLATFORM_PPS GPCCR_PPS_4GB +#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS + #endif /* ARM_PAS_DEF_H */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 758a061b8..ef372068a 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -17,10 +18,12 @@ #include #include #include +#include #ifdef SPD_opteed #include #endif #include +#include #include #include @@ -111,8 +114,10 @@ void bl2_plat_preload_setup(void) */ void arm_bl2_platform_setup(void) { +#if !ENABLE_RME /* Initialize the secure environment */ plat_arm_security_setup(); +#endif #if defined(PLAT_ARM_MEM_PROT_ADDR) arm_nor_psci_do_static_mem_protect(); @@ -124,9 +129,47 @@ void bl2_platform_setup(void) arm_bl2_platform_setup(); } +#if ENABLE_RME +static void arm_bl2_plat_gpt_setup(void) +{ + /* + * The GPT library might modify the gpt regions structure to optimize + * the layout, so the array cannot be constant. + */ + pas_region_t pas_regions[] = { + ARM_PAS_GPI_ANY, + ARM_PAS_KERNEL, + ARM_PAS_TZC, + ARM_PAS_REALM, + ARM_PAS_EL3_DRAM, + ARM_PAS_GPTS + }; + + gpt_init_params_t gpt_params = { + PLATFORM_PGS, + PLATFORM_PPS, + PLATFORM_L0GPTSZ, + pas_regions, + (unsigned int)(sizeof(pas_regions)/sizeof(pas_region_t)), + ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, + ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE + }; + + /* Initialise the global granule tables */ + INFO("Enabling Granule Protection Checks\n"); + if (gpt_init(&gpt_params) < 0) { + panic(); + } + + gpt_enable(); +} +#endif /* ENABLE_RME */ + /******************************************************************************* - * Perform the very early platform specific architectural setup here. At the - * moment this is only initializes the mmu in a quick and dirty way. + * Perform the very early platform specific architectural setup here. + * When RME is enabled the secure environment is initialised before + * initialising and enabling Granule Protection. + * This function initialises the MMU in a quick and dirty way. ******************************************************************************/ void arm_bl2_plat_arch_setup(void) { @@ -155,10 +198,23 @@ void arm_bl2_plat_arch_setup(void) {0} }; +#if ENABLE_RME + /* Initialise the secure environment */ + plat_arm_security_setup(); + + /* Initialise and enable Granule Protection */ + arm_bl2_plat_gpt_setup(); +#endif setup_page_tables(bl_regions, plat_arm_get_mmap()); #ifdef __aarch64__ +#if ENABLE_RME + /* BL2 runs in EL3 when RME enabled. */ + assert(get_armv9_2_feat_rme_support() != 0U); + enable_mmu_el3(0); +#else enable_mmu_el1(0); +#endif #else enable_mmu_svc_mon(0); #endif diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index d2bacd3fa..d76031282 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -229,6 +231,28 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi */ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; #endif + +#if ENABLE_RME + /* + * Initialise Granule Protection library and enable GPC + * for the primary processor. The tables were initialised + * in BL2, so there is no need to provide any PAS here. + */ + gpt_init_params_t gpt_params = { + PLATFORM_PGS, + PLATFORM_PPS, + PLATFORM_L0GPTSZ, + NULL, + 0U, + ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, + ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE + }; + + /* Initialise the global granule tables. */ + if (gpt_init(&gpt_params) < 0) { + panic(); + } +#endif /* ENABLE_RME */ } void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, -- cgit v1.2.3 From dbbc9a6790e8da63e5b2c19b7e01a2c303b156e3 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Tue, 13 Jul 2021 18:59:19 -0500 Subject: refactor(plat/fvp): update FVP platform DTS for FEAT_RME This patch make minor modifications to FVP DTS including modifying the Non-secure memory range when RME is enabled. Signed-off-by: Zelalem Aweke Change-Id: I6b3650a2abfff10462a8a2d42755e6d764f7b035 --- fdts/fvp-base-gicv3-psci-common.dtsi | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index b6753de8e..3cb613f63 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -24,7 +24,11 @@ #address-cells = <2>; #size-cells = <2>; - chosen { }; +#if (ENABLE_RME == 1) + chosen { bootargs = "mem=1G console=ttyAMA0 earlycon=pl011,0x1c090000 root=/dev/vda ip=on";}; +#else + chosen {}; +#endif aliases { serial0 = &v2m_serial0; @@ -135,8 +139,13 @@ memory@80000000 { device_type = "memory"; +#if (ENABLE_RME == 1) + reg = <0x00000000 0x80000000 0 0x7C000000>, + <0x00000008 0x80000000 0 0x80000000>; +#else reg = <0x00000000 0x80000000 0 0x7F000000>, <0x00000008 0x80000000 0 0x80000000>; +#endif }; gic: interrupt-controller@2f000000 { -- cgit v1.2.3 From 707f0710490a2e1c8442f16b12aa94edd4ac6cd3 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Mon, 26 Jul 2021 21:28:42 -0500 Subject: refactor(plat/arm): rename ARM_DTB_DRAM_NS region macros The macros PLAT_HW_CONFIG_DTB_BASE and PLAT_HW_CONFIG_DTB_SIZE describe the range of memory where the HW_CONFIG_DTB can be loaded rather than the actual load address and size of the DTB. This patch changes the names to something more descriptive. Signed-off-by: Zelalem Aweke Change-Id: I98b81f3ce0c80fd76614f959667c25b07941e190 --- plat/arm/board/fvp/include/platform_def.h | 9 +++++---- plat/arm/board/juno/include/platform_def.h | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 6e72b5999..541842fde 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -66,12 +66,13 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x880000000) #define PLAT_ARM_DRAM2_SIZE UL(0x80000000) -#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000) -#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) +/* Range of kernel DTB load address */ +#define FVP_DTB_DRAM_MAP_START ULL(0x82000000) +#define FVP_DTB_DRAM_MAP_SIZE ULL(0x8000) #define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ - PLAT_HW_CONFIG_DTB_BASE, \ - PLAT_HW_CONFIG_DTB_SIZE, \ + FVP_DTB_DRAM_MAP_START, \ + FVP_DTB_DRAM_MAP_SIZE, \ MT_MEMORY | MT_RO | MT_NS) /* * Load address of BL33 for this platform port diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 5299a7b8a..d61ba5d19 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -53,12 +53,13 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x880000000) #define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) -#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000) -#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x00008000) /* 32KB */ +/* Range of kernel DTB load address */ +#define JUNO_DTB_DRAM_MAP_START ULL(0x82000000) +#define JUNO_DTB_DRAM_MAP_SIZE ULL(0x00008000) /* 32KB */ #define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ - PLAT_HW_CONFIG_DTB_BASE, \ - PLAT_HW_CONFIG_DTB_SIZE, \ + JUNO_DTB_DRAM_MAP_START, \ + JUNO_DTB_DRAM_MAP_SIZE, \ MT_MEMORY | MT_RO | MT_NS) /* virtual address used by dynamic mem_protect for chunk_base */ -- cgit v1.2.3 From 672d669d6c72f92c6b81464d1d421e392bc1aa3e Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Mon, 26 Jul 2021 21:39:05 -0500 Subject: fix(plat/fvp): allow changing the kernel DTB load address We currently use ARM_PRELOADED_DTB_BASE build variable to pass the kernel DTB base address to the kernel when using the ARM_LINUX_KERNEL_AS_BL33 option. However this variable doesn't actually change the DTB load address. The DTB load address is actually specified in the FW_CONFIG DTS (fvp_fw_config.dts) as 'hw_config'. This patch passes the hw_config value instead of ARM_PRELOADED_DTB_BASE allowing us to change the kernel DTB load address through fvp_fw_config.dts. With this change we don't need the ARM_PRELOADED_DTB_BASE build variable if RESET_TO_BL31 is not set. Note that the hw_config value needs to be within the ARM_DTB_DRAM_NS region specified by FVP_DTB_DRAM_MAP_START and FVP_DTB_DRAM_MAP_SIZE. This patch also expands the ARM_DTB_DRAM_NS region to 32MB. Signed-off-by: Zelalem Aweke Change-Id: Idd74cdf5d2c649bb320644392ba5d69e175a53a9 --- plat/arm/board/fvp/include/platform_def.h | 2 +- plat/arm/common/arm_bl31_setup.c | 4 ++++ plat/arm/common/arm_common.mk | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 541842fde..90bb13568 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -68,7 +68,7 @@ /* Range of kernel DTB load address */ #define FVP_DTB_DRAM_MAP_START ULL(0x82000000) -#define FVP_DTB_DRAM_MAP_SIZE ULL(0x8000) +#define FVP_DTB_DRAM_MAP_SIZE ULL(0x02000000) /* 32 MB */ #define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ FVP_DTB_DRAM_MAP_START, \ diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index d76031282..d131bb95b 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -218,7 +218,11 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi * tree blob (DTB) in x0, while x1-x3 are reserved for future use and * must be 0. */ +#if RESET_TO_BL31 bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE; +#else + bl33_image_ep_info.args.arg0 = (u_register_t)hw_config; +#endif bl33_image_ep_info.args.arg1 = 0U; bl33_image_ep_info.args.arg2 = 0U; bl33_image_ep_info.args.arg3 = 0U; diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index dc8c6d01e..ae9afb795 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -94,10 +94,13 @@ ifeq (${ARM_LINUX_KERNEL_AS_BL33},1) ifndef PRELOADED_BL33_BASE $(error "PRELOADED_BL33_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.") endif - ifndef ARM_PRELOADED_DTB_BASE - $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.") + ifeq (${RESET_TO_BL31},1) + ifndef ARM_PRELOADED_DTB_BASE + $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is + used with RESET_TO_BL31.") + endif + $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) endif - $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) endif # Arm Ethos-N NPU SiP service -- cgit v1.2.3 From d22f1d358731f0f55f2f392fa587f0fa8d315aa5 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Fri, 18 Jun 2021 12:25:35 +0100 Subject: fix(plat/fvp): bump BL2 stack size VERBOSE print logs need a larger stack size and the currently configured BL2 stack size was insufficient for FVP. This patch increases the same. Signed-off-by: Soby Mathew Change-Id: I316ba2ea467571161b5f4807e6e5fa0bf89d44c6 --- plat/arm/board/fvp/include/platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 90bb13568..96574e526 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -196,7 +196,7 @@ # if TRUSTED_BOARD_BOOT # define PLATFORM_STACK_SIZE UL(0x1000) # else -# define PLATFORM_STACK_SIZE UL(0x440) +# define PLATFORM_STACK_SIZE UL(0x600) # endif #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE UL(0x400) -- cgit v1.2.3 From 3cfa3497bace3e77fd1020fb125b130756c54355 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 26 Aug 2021 15:29:47 -0500 Subject: docs(rme): add build and run instructions for FEAT_RME This patch adds instructions on how to build and run TF-A with FEAT_RME enabled. The patch also adds code owners for FEAT_RME. Signed-off-by: Zelalem Aweke Change-Id: Id16dc52cb76b1ea56ac5c3fc38cb0794a62ac2a1 --- docs/about/maintainers.rst | 10 ++ docs/components/index.rst | 1 + docs/components/realm-management-extension.rst | 194 +++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 docs/components/realm-management-extension.rst diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 1bd46663a..7db81fcc6 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -109,6 +109,16 @@ Exception Handling Framework (EHF) :|G|: `john-powell-arm`_ :|F|: bl31/ehf.c +Realm Management Extension (RME) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: Bipin Ravi +:|G|: `bipinravi-arm`_ +:|M|: Mark Dykes +:|G|: `mardyk01`_ +:|M|: John Powell +:|G|: `john-powell-arm`_ +:|M|: Zelalem Aweke +:|G|: `zelalem-aweke`_ Drivers, Libraries and Framework Code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/components/index.rst b/docs/components/index.rst index 2409f964b..f349d8dcc 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -22,3 +22,4 @@ Components ffa-manifest-binding xlat-tables-lib-v2-design cot-binding + realm-management-extension diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst new file mode 100644 index 000000000..5c580f36d --- /dev/null +++ b/docs/components/realm-management-extension.rst @@ -0,0 +1,194 @@ + +Realm Management Extension (RME) +==================================== + +FEAT_RME (or RME for short) is an Armv9-A extension and is one component of the +`Arm Confidential Compute Architecture (Arm CCA)`_. TF-A supports RME starting +from version 2.6. This document provides instructions on how to build and run +TF-A with RME. + +Building and running TF-A with RME +------------------------------------ + +This section describes how you can build and run TF-A with RME enabled. +We assume you have all the :ref:`Prerequisites` to build TF-A. + +To enable RME, you need to set the ENABLE_RME build flag when building +TF-A. Currently, this feature is only supported for the FVP platform. + +The following instructions show you how to build and run TF-A with RME +for two scenarios: TF-A with TF-A Tests, and four-world execution with +Hafnium and TF-A Tests. The instructions assume you have already obtained +TF-A. You can use the following command to clone TF-A. + +.. code:: shell + + git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git + +To run the tests, you need an FVP model. You can download a model that supports +RME from the `Arm Architecture Models website`_. Please select the +*Base RevC AEM FVP* model. After extracting the downloaded file, you should be able to +find the *FVP_Base_RevC-2xAEMvA* binary. The instructions below have been tested +with model version 11.15 revision 18. + +.. note:: + + ENABLE_RME build option is currently experimental. + +Building TF-A with TF-A Tests +******************************************** +Use the following instructions to build TF-A with `TF-A Tests`_ as the +non-secure payload (BL33). + +**1. Obtain and build TF-A Tests** + +.. code:: shell + + git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git + cd tf-a-tests + make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 + +This produces a TF-A Tests binary (*tftf.bin*) in the *build/fvp/debug* directory. + +**2. Build TF-A** + +.. code:: shell + + cd trusted-firmware-a + make CROSS_COMPILE=aarch64-none-elf- \ + PLAT=fvp \ + ENABLE_RME=1 \ + FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \ + DEBUG=1 \ + BL33= \ + all fip + +This produces *bl1.bin* and *fip.bin* binaries in the *build/fvp/debug* directory. +The above command also builds a Test Realm Payload (TRP), which is a small test +payload that implements Realm Monitor Management (RMM) functionalities and runs +in the realm world (R-EL2). The TRP binary is packaged in *fip.bin*. + +Four-world execution with Hafnium and TF-A Tests +**************************************************** +Four-world execution involves software components at each security state: root, +secure, realm and non-secure. This section describes how to build TF-A +with four-world support. We use TF-A as the root firmware, `Hafnium`_ as the +secure component, TRP as the realm-world firmware and TF-A Tests as the +non-secure payload. + +Before building TF-A, you first need to build the other software components. +You can find instructions on how to get and build TF-A Tests above. + +**1. Obtain and build Hafnium** + +.. code:: shell + + git clone --recurse-submodules https://git.trustedfirmware.org/hafnium/hafnium.git + cd hafnium + make PROJECT=reference + +The Hafnium binary should be located at +*out/reference/secure_aem_v8a_fvp_clang/hafnium.bin* + +**2. Build TF-A** + +Build TF-A with RME as well as SPM enabled. + +.. code:: shell + + make CROSS_COMPILE=aarch64-none-elf- \ + PLAT=fvp \ + ENABLE_RME=1 \ + FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \ + SPD=spmd \ + SPMD_SPM_AT_SEL2=1 \ + BRANCH_PROTECTION=1 \ + CTX_INCLUDE_PAUTH_REGS=1 \ + DEBUG=1 \ + SP_LAYOUT_FILE=/build/fvp/debug/sp_layout.json> \ + BL32= \ + BL33= \ + all fip + +Running the tests +********************* +Use the following command to run the tests on FVP. TF-A Tests should boot +and run the default tests including RME tests. + +.. code:: shell + + FVP_Base_RevC-2xAEMvA \ + -C bp.flashloader0.fname= \ + -C bp.secureflashloader.fname= \ + -C bp.refcounter.non_arch_start_at_default=1 \ + -C bp.refcounter.use_real_time=0 \ + -C bp.ve_sysregs.exit_on_shutdown=1 \ + -C cache_state_modelled=1 \ + -C cluster0.NUM_CORES=4 \ + -C cluster0.PA_SIZE=48 \ + -C cluster0.ecv_support_level=2 \ + -C cluster0.gicv3.cpuintf-mmap-access-level=2 \ + -C cluster0.gicv3.without-DS-support=1 \ + -C cluster0.gicv4.mask-virtual-interrupt=1 \ + -C cluster0.has_arm_v8-6=1 \ + -C cluster0.has_branch_target_exception=1 \ + -C cluster0.has_rme=1 \ + -C cluster0.has_rndr=1 \ + -C cluster0.has_amu=1 \ + -C cluster0.has_v8_7_pmu_extension=2 \ + -C cluster0.max_32bit_el=-1 \ + -C cluster0.restriction_on_speculative_execution=2 \ + -C cluster0.restriction_on_speculative_execution_aarch32=2 \ + -C cluster1.NUM_CORES=4 \ + -C cluster1.PA_SIZE=48 \ + -C cluster1.ecv_support_level=2 \ + -C cluster1.gicv3.cpuintf-mmap-access-level=2 \ + -C cluster1.gicv3.without-DS-support=1 \ + -C cluster1.gicv4.mask-virtual-interrupt=1 \ + -C cluster1.has_arm_v8-6=1 \ + -C cluster1.has_branch_target_exception=1 \ + -C cluster1.has_rme=1 \ + -C cluster1.has_rndr=1 \ + -C cluster1.has_amu=1 \ + -C cluster1.has_v8_7_pmu_extension=2 \ + -C cluster1.max_32bit_el=-1 \ + -C cluster1.restriction_on_speculative_execution=2 \ + -C cluster1.restriction_on_speculative_execution_aarch32=2 \ + -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 \ + -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \ + -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 \ + -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \ + -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475 \ + -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \ + -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 \ + -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0 \ + -C bp.pl011_uart0.out_file=uart0.log \ + -C bp.pl011_uart1.out_file=uart1.log \ + -C bp.pl011_uart2.out_file=uart2.log \ + -C pctl.startup=0.0.0.0 \ + -Q 1000 \ + "$@" + +The bottom of the output from *uart0* should look something like the following. + +.. code-block:: shell + + ... + + > Test suite 'FF-A Interrupt' + Passed + > Test suite 'SMMUv3 tests' + Passed + > Test suite 'PMU Leakage' + Passed + > Test suite 'DebugFS' + Passed + > Test suite 'Realm payload tests' + Passed + ... + + +.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture +.. _Arm Architecture Models website: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models +.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest +.. _Hafnium: https://www.trustedfirmware.org/projects/hafnium -- cgit v1.2.3 From 07e96d1d2958b6f121476fd391ac67bf8c2c4735 Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 1 Oct 2021 12:30:49 -0500 Subject: feat(rme): disable Watchdog for Arm platforms if FEAT_RME enabled In the typical TF-A boot flow, the Trusted Watchdog is started at the beginning of BL1 and then stopped in BL1 after returning from BL2. However, in the RME boot flow there is no return path from BL2 to BL1. Therefore, disable the Watchdog if ENABLE_RME is set. Signed-off-by: Zelalem Aweke Change-Id: Id88fbfab8e8440642414bed48c50e3fcb23f3621 --- plat/arm/common/arm_common.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index ae9afb795..d14d10143 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -52,9 +52,10 @@ $(eval $(call assert_boolean,ARM_RECOM_STATE_ID_ENC)) $(eval $(call add_define,ARM_RECOM_STATE_ID_ENC)) # Process ARM_DISABLE_TRUSTED_WDOG flag -# By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set +# By default, Trusted Watchdog is always enabled unless +# SPIN_ON_BL1_EXIT or ENABLE_RME is set ARM_DISABLE_TRUSTED_WDOG := 0 -ifeq (${SPIN_ON_BL1_EXIT}, 1) +ifneq ($(filter 1,${SPIN_ON_BL1_EXIT} ${ENABLE_RME}),) ARM_DISABLE_TRUSTED_WDOG := 1 endif $(eval $(call assert_boolean,ARM_DISABLE_TRUSTED_WDOG)) -- cgit v1.2.3 From f19dc624a17c9df6aa444e33568b1f70ff4e9341 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 16 Jun 2021 17:57:28 -0500 Subject: refactor(gpt): productize and refactor GPT library This patch updates and refactors the GPT library and fixes bugs. - Support all combinations of PGS, PPS, and L0GPTSZ parameters. - PPS and PGS are set at runtime, L0GPTSZ is read from GPCCR_EL3. - Use compiler definitions to simplify code. - Renaming functions to better suit intended uses. - MMU enabled before GPT APIs called. - Add comments to make function usage more clear in GPT library. - Added _rme suffix to file names to differentiate better from the GPT file system code. - Renamed gpt_defs.h to gpt_rme_private.h to better separate private and public code. - Renamed gpt_core.c to gpt_rme.c to better conform to TF-A precedent. Signed-off-by: John Powell Change-Id: I4cbb23b0f81e697baa9fb23ba458aa3f7d1ed919 --- bl2/bl2.mk | 2 +- bl31/aarch64/bl31_entrypoint.S | 21 +- bl31/bl31.mk | 2 +- include/arch/aarch64/arch.h | 78 --- include/lib/gpt/gpt.h | 86 --- include/lib/gpt/gpt_defs.h | 76 --- include/lib/gpt_rme/gpt_rme.h | 276 ++++++++ include/plat/arm/common/arm_def.h | 98 +-- include/plat/arm/common/arm_pas_def.h | 47 +- lib/gpt/gpt.mk | 8 - lib/gpt/gpt_core.c | 767 ----------------------- lib/gpt_rme/gpt_rme.c | 1112 +++++++++++++++++++++++++++++++++ lib/gpt_rme/gpt_rme.mk | 8 + lib/gpt_rme/gpt_rme_private.h | 228 +++++++ plat/arm/common/arm_bl2_setup.c | 49 +- plat/arm/common/arm_bl31_setup.c | 40 +- services/std_svc/rmmd/rmmd_main.c | 16 +- 17 files changed, 1767 insertions(+), 1147 deletions(-) delete mode 100644 include/lib/gpt/gpt.h delete mode 100644 include/lib/gpt/gpt_defs.h create mode 100644 include/lib/gpt_rme/gpt_rme.h delete mode 100644 lib/gpt/gpt.mk delete mode 100644 lib/gpt/gpt_core.c create mode 100644 lib/gpt_rme/gpt_rme.c create mode 100644 lib/gpt_rme/gpt_rme.mk create mode 100644 lib/gpt_rme/gpt_rme_private.h diff --git a/bl2/bl2.mk b/bl2/bl2.mk index fd8374795..7a973e512 100644 --- a/bl2/bl2.mk +++ b/bl2/bl2.mk @@ -17,7 +17,7 @@ endif ifeq (${ENABLE_RME},1) # Using RME, run BL2 at EL3 -include lib/gpt/gpt.mk +include lib/gpt_rme/gpt_rme.mk BL2_SOURCES += bl2/${ARCH}/bl2_rme_entrypoint.S \ bl2/${ARCH}/bl2_el3_exceptions.S \ diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S index 2e9a39496..ed058648f 100644 --- a/bl31/aarch64/bl31_entrypoint.S +++ b/bl31/aarch64/bl31_entrypoint.S @@ -172,14 +172,6 @@ func bl31_warm_entrypoint _exception_vectors=runtime_exceptions \ _pie_fixup_size=0 -#if ENABLE_RME - /* - * Initialise and enable Granule Protection - * before enabling any stage of translation. - */ - bl gpt_enable -#endif - /* * We're about to enable MMU and participate in PSCI state coordination. * @@ -203,6 +195,19 @@ func bl31_warm_entrypoint #endif bl bl31_plat_enable_mmu +#if ENABLE_RME + /* + * At warm boot GPT data structures have already been initialized in RAM + * but the sysregs for this CPU need to be initialized. Note that the GPT + * accesses are controlled attributes in GPCCR and do not depend on the + * SCR_EL3.C bit. + */ + bl gpt_enable + cbz x0, 1f + no_ret plat_panic_handler +1: +#endif + #if ENABLE_PAUTH /* -------------------------------------------------------------------- * Program APIAKey_EL1 and enable pointer authentication diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 5927fb1c9..106d4109d 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -112,7 +112,7 @@ BL31_SOURCES += services/std_svc/pci_svc.c endif ifeq (${ENABLE_RME},1) -include lib/gpt/gpt.mk +include lib/gpt_rme/gpt_rme.mk BL31_SOURCES += ${GPT_LIB_SRCS} \ ${RMMD_SOURCES} diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 5949370e0..0ad97543b 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1105,87 +1105,9 @@ /******************************************************************************* * Realm management extension register definitions ******************************************************************************/ - -/* GPCCR_EL3 definitions */ #define GPCCR_EL3 S3_6_C2_C1_6 - -/* Least significant address bits protected by each entry in level 0 GPT */ -#define GPCCR_L0GPTSZ_SHIFT U(20) -#define GPCCR_L0GPTSZ_MASK U(0xF) -#define GPCCR_L0GPTSZ_30BITS U(0x0) -#define GPCCR_L0GPTSZ_34BITS U(0x4) -#define GPCCR_L0GPTSZ_36BITS U(0x6) -#define GPCCR_L0GPTSZ_39BITS U(0x9) -#define SET_GPCCR_L0GPTSZ(x) \ - ((x & GPCCR_L0GPTSZ_MASK) << GPCCR_L0GPTSZ_SHIFT) - -/* Granule protection check priority bit definitions */ -#define GPCCR_GPCP_SHIFT U(17) -#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) - -/* Granule protection check bit definitions */ -#define GPCCR_GPC_SHIFT U(16) -#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) - -/* Physical granule size bit definitions */ -#define GPCCR_PGS_SHIFT U(14) -#define GPCCR_PGS_MASK U(0x3) -#define GPCCR_PGS_4K U(0x0) -#define GPCCR_PGS_16K U(0x2) -#define GPCCR_PGS_64K U(0x1) -#define SET_GPCCR_PGS(x) \ - ((x & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) - -/* GPT fetch shareability attribute bit definitions */ -#define GPCCR_SH_SHIFT U(12) -#define GPCCR_SH_MASK U(0x3) -#define GPCCR_SH_NS U(0x0) -#define GPCCR_SH_OS U(0x2) -#define GPCCR_SH_IS U(0x3) -#define SET_GPCCR_SH(x) \ - ((x & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) - -/* GPT fetch outer cacheability attribute bit definitions */ -#define GPCCR_ORGN_SHIFT U(10) -#define GPCCR_ORGN_MASK U(0x3) -#define GPCCR_ORGN_NC U(0x0) -#define GPCCR_ORGN_WB_RA_WA U(0x1) -#define GPCCR_ORGN_WT_RA_NWA U(0x2) -#define GPCCR_ORGN_WB_RA_NWA U(0x3) -#define SET_GPCCR_ORGN(x) \ - ((x & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) - -/* GPT fetch inner cacheability attribute bit definitions */ -#define GPCCR_IRGN_SHIFT U(8) -#define GPCCR_IRGN_MASK U(0x3) -#define GPCCR_IRGN_NC U(0x0) -#define GPCCR_IRGN_WB_RA_WA U(0x1) -#define GPCCR_IRGN_WT_RA_NWA U(0x2) -#define GPCCR_IRGN_WB_RA_NWA U(0x3) -#define SET_GPCCR_IRGN(x) \ - ((x & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) - -/* Protected physical address size bit definitions */ -#define GPCCR_PPS_SHIFT U(0) -#define GPCCR_PPS_MASK U(0x7) -#define GPCCR_PPS_4GB U(0x0) -#define GPCCR_PPS_64GB U(0x1) -#define GPCCR_PPS_1TB U(0x2) -#define GPCCR_PPS_4TB U(0x3) -#define GPCCR_PPS_16TB U(0x4) -#define GPCCR_PPS_256TB U(0x5) -#define GPCCR_PPS_4PB U(0x6) -#define SET_GPCCR_PPS(x) \ - ((x & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) - -/* GPTBR_EL3 definitions */ #define GPTBR_EL3 S3_6_C2_C1_4 -/* Base Address for the GPT bit definitions */ -#define GPTBR_BADDR_SHIFT U(0) -#define GPTBR_BADDR_VAL_SHIFT U(12) -#define GPTBR_BADDR_MASK ULL(0xffffffffff) - /******************************************************************************* * RAS system registers ******************************************************************************/ diff --git a/include/lib/gpt/gpt.h b/include/lib/gpt/gpt.h deleted file mode 100644 index 89d30177d..000000000 --- a/include/lib/gpt/gpt.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GPT_H -#define GPT_H - -#include - -#include - -#include "gpt_defs.h" - -#define GPT_DESC_ATTRS(_type, _gpi) \ - ((((_type) & PAS_REG_DESC_TYPE_MASK) \ - << PAS_REG_DESC_TYPE_SHIFT) | \ - (((_gpi) & PAS_REG_GPI_MASK) \ - << PAS_REG_GPI_SHIFT)) - -/* - * Macro to create a GPT entry for this PAS range either as a L0 block - * descriptor or L1 table descriptor depending upon the size of the range. - */ -#define MAP_GPT_REGION(_pa, _sz, _gpi) \ - { \ - .base_pa = (_pa), \ - .size = (_sz), \ - .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_ANY, (_gpi)), \ - } - -/* - * Special macro to create a L1 table descriptor at L0 for a 1GB region as - * opposed to creating a block mapping by default. - */ -#define MAP_GPT_REGION_TBL(_pa, _sz, _gpi) \ - { \ - .base_pa = (_pa), \ - .size = (_sz), \ - .attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, (_gpi)), \ - } - -/* - * Structure for specifying a Granule range and its properties - */ -typedef struct pas_region { - unsigned long long base_pa; /**< Base address for PAS. */ - size_t size; /**< Size of the PAS. */ - unsigned int attrs; /**< PAS GPI and entry type. */ -} pas_region_t; - -/* - * Structure to initialise the Granule Protection Tables. - */ -typedef struct gpt_init_params { - unsigned int pgs; /**< Address Width of Phisical Granule Size. */ - unsigned int pps; /**< Protected Physical Address Size. */ - unsigned int l0gptsz; /**< Granule size on L0 table entry. */ - pas_region_t *pas_regions; /**< PAS regions to protect. */ - unsigned int pas_count; /**< Number of PAS regions to initialise. */ - uintptr_t l0_mem_base; /**< L0 Table base address. */ - size_t l0_mem_size; /**< Size of memory reserved for L0 tables. */ - uintptr_t l1_mem_base; /**< L1 Table base address. */ - size_t l1_mem_size; /**< Size of memory reserved for L1 tables. */ -} gpt_init_params_t; - -/** @brief Initialise the Granule Protection tables. - */ -int gpt_init(gpt_init_params_t *params); - -/** @brief Enable the Granule Protection Checks. - */ -void gpt_enable(void); - -/** @brief Disable the Granule Protection Checks. - */ -void gpt_disable(void); - -/** @brief Transition a granule between security states. - */ -int gpt_transition_pas(uint64_t pa, - unsigned int src_sec_state, - unsigned int target_pas); - -#endif /* GPT_H */ diff --git a/include/lib/gpt/gpt_defs.h b/include/lib/gpt/gpt_defs.h deleted file mode 100644 index 6122a126f..000000000 --- a/include/lib/gpt/gpt_defs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GPT_DEFS_H -#define GPT_DEFS_H - -#include -#include - -#include "gpt.h" - -/* GPI values */ -#define GPI_NO_ACCESS U(0x0) -#define GPI_SECURE U(0x8) -#define GPI_NS U(0x9) -#define GPI_ROOT U(0xa) -#define GPI_REALM U(0xb) -#define GPI_ANY U(0xf) -#define GPI_VAL_MASK ULL(0xf) - -/* GPT descriptor bit definitions */ -#define GPT_L1_INDEX_MASK ULL(0xf) -#define GPT_L1_INDEX_SHIFT ULL(0x0) - -#define GPT_TBL_DESC ULL(0x3) -#define GPT_BLK_DESC ULL(0x1) - -#define GPT_TBL_DESC_ADDR_SHIFT ULL(12) -#define GPT_TBL_DESC_ADDR_MASK (((ULL(1) << \ - (51 - GPT_TBL_DESC_ADDR_SHIFT)) - 1) \ - << GPT_TBL_DESC_ADDR_SHIFT) - -#define GPT_BLOCK_DESC_GPI_VAL_SHIFT ULL(4) - -/* Each descriptor is 8 bytes long. */ -#define GPT_DESC_SIZE ULL(8) - -#define PPS_MAX_VAL PSTCR_EL3_PPS_4PB -#define PPS_NUM_1GB_ENTRIES ULL(1024) -#define PGS_4K_1GB_L1_TABLE_SZ (U(2) << 17) - -/* 2 << LOG2_8K = Bytes in 8K */ -#define LOG2_8K U(13) - -#define GPT_L1_SIZE ULL(0x40000) /* 256K */ -#define SZ_1G (ULL(0x1) << 30) /* 1GB */ - -#define GPT_MIN_PGS_SHIFT U(12) /* 4K */ - -#define L1_GPT_INDEX_MASK U(0x3fffffff) -#define GPT_GRAN_DESC_NUM_GPIS U(4) - -#define PAS_REG_GPI_SHIFT U(0) -#define PAS_REG_GPI_MASK U(0xf) - -/* .attrs field definitions */ -#define PAS_REG_DESC_TYPE_ANY U(0) -#define PAS_REG_DESC_TYPE_BLK U(1) -#define PAS_REG_DESC_TYPE_TBL U(2) -#define PAS_REG_DESC_TYPE_SHIFT U(4) -#define PAS_REG_DESC_TYPE_MASK U(0x3) -#define PAS_REG_DESC_TYPE(_attrs) (((_attrs) \ - >> PAS_REG_DESC_TYPE_SHIFT) \ - & PAS_REG_DESC_TYPE_MASK) - -#define PAS_REG_GPI(_attrs) (((_attrs) \ - >> PAS_REG_GPI_SHIFT) \ - & PAS_REG_GPI_MASK) - -#define SZ_1G_MASK (SZ_1G - U(1)) -#define IS_1GB_ALIGNED(addr) (((addr) & SZ_1G_MASK) == U(0)) - -#endif /* GPT_DEFS */ diff --git a/include/lib/gpt_rme/gpt_rme.h b/include/lib/gpt_rme/gpt_rme.h new file mode 100644 index 000000000..379b91562 --- /dev/null +++ b/include/lib/gpt_rme/gpt_rme.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_RME_H +#define GPT_RME_H + +#include + +#include + +/******************************************************************************/ +/* GPT helper macros and definitions */ +/******************************************************************************/ + +/* + * Structure for specifying a mapping range and it's properties. This should not + * be manually initialized, using the MAP_GPT_REGION_x macros is recommended as + * to avoid potential incompatibilities in the future. + */ +typedef struct pas_region { + uintptr_t base_pa; /* Base address for PAS. */ + size_t size; /* Size of the PAS. */ + unsigned int attrs; /* PAS GPI and entry type. */ +} pas_region_t; + +/* GPT GPI definitions */ +#define GPT_GPI_NO_ACCESS U(0x0) +#define GPT_GPI_SECURE U(0x8) +#define GPT_GPI_NS U(0x9) +#define GPT_GPI_ROOT U(0xA) +#define GPT_GPI_REALM U(0xB) +#define GPT_GPI_ANY U(0xF) +#define GPT_GPI_VAL_MASK UL(0xF) + +/* PAS attribute GPI definitions. */ +#define GPT_PAS_ATTR_GPI_SHIFT U(0) +#define GPT_PAS_ATTR_GPI_MASK U(0xF) +#define GPT_PAS_ATTR_GPI(_attrs) (((_attrs) \ + >> GPT_PAS_ATTR_GPI_SHIFT) \ + & GPT_PAS_ATTR_GPI_MASK) + +/* PAS attribute mapping type definitions */ +#define GPT_PAS_ATTR_MAP_TYPE_BLOCK U(0x0) +#define GPT_PAS_ATTR_MAP_TYPE_GRANULE U(0x1) +#define GPT_PAS_ATTR_MAP_TYPE_SHIFT U(4) +#define GPT_PAS_ATTR_MAP_TYPE_MASK U(0x1) +#define GPT_PAS_ATTR_MAP_TYPE(_attrs) (((_attrs) \ + >> GPT_PAS_ATTR_MAP_TYPE_SHIFT) \ + & GPT_PAS_ATTR_MAP_TYPE_MASK) + +/* + * Macro to initialize the attributes field in the pas_region_t structure. + * [31:5] Reserved + * [4] Mapping type (GPT_PAS_ATTR_MAP_TYPE_x definitions) + * [3:0] PAS GPI type (GPT_GPI_x definitions) + */ +#define GPT_PAS_ATTR(_type, _gpi) \ + ((((_type) & GPT_PAS_ATTR_MAP_TYPE_MASK) \ + << GPT_PAS_ATTR_MAP_TYPE_SHIFT) | \ + (((_gpi) & GPT_PAS_ATTR_GPI_MASK) \ + << GPT_PAS_ATTR_GPI_SHIFT)) + +/* + * Macro to create a GPT entry for this PAS range as a block descriptor. If this + * region does not fit the requirements for a block descriptor then GPT + * initialization will fail. + */ +#define GPT_MAP_REGION_BLOCK(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_BLOCK, (_gpi)), \ + } + +/* + * Macro to create a GPT entry for this PAS range as a table descriptor. If this + * region does not fit the requirements for a table descriptor then GPT + * initialization will fail. + */ +#define GPT_MAP_REGION_GRANULE(_pa, _sz, _gpi) \ + { \ + .base_pa = (_pa), \ + .size = (_sz), \ + .attrs = GPT_PAS_ATTR(GPT_PAS_ATTR_MAP_TYPE_GRANULE, (_gpi)), \ + } + +/******************************************************************************/ +/* GPT register field definitions */ +/******************************************************************************/ + +/* + * Least significant address bits protected by each entry in level 0 GPT. This + * field is read-only. + */ +#define GPCCR_L0GPTSZ_SHIFT U(20) +#define GPCCR_L0GPTSZ_MASK U(0xF) + +typedef enum { + GPCCR_L0GPTSZ_30BITS = U(0x0), + GPCCR_L0GPTSZ_34BITS = U(0x4), + GPCCR_L0GPTSZ_36BITS = U(0x6), + GPCCR_L0GPTSZ_39BITS = U(0x9) +} gpccr_l0gptsz_e; + +/* Granule protection check priority bit definitions */ +#define GPCCR_GPCP_SHIFT U(17) +#define GPCCR_GPCP_BIT (ULL(1) << GPCCR_EL3_GPCP_SHIFT) + +/* Granule protection check bit definitions */ +#define GPCCR_GPC_SHIFT U(16) +#define GPCCR_GPC_BIT (ULL(1) << GPCCR_GPC_SHIFT) + +/* Physical granule size bit definitions */ +#define GPCCR_PGS_SHIFT U(14) +#define GPCCR_PGS_MASK U(0x3) +#define SET_GPCCR_PGS(x) (((x) & GPCCR_PGS_MASK) << GPCCR_PGS_SHIFT) + +typedef enum { + GPCCR_PGS_4K = U(0x0), + GPCCR_PGS_64K = U(0x1), + GPCCR_PGS_16K = U(0x2) +} gpccr_pgs_e; + +/* GPT fetch shareability attribute bit definitions */ +#define GPCCR_SH_SHIFT U(12) +#define GPCCR_SH_MASK U(0x3) +#define SET_GPCCR_SH(x) (((x) & GPCCR_SH_MASK) << GPCCR_SH_SHIFT) + +typedef enum { + GPCCR_SH_NS = U(0x0), + GPCCR_SH_OS = U(0x2), + GPCCR_SH_IS = U(0x3) +} gpccr_sh_e; + +/* GPT fetch outer cacheability attribute bit definitions */ +#define GPCCR_ORGN_SHIFT U(10) +#define GPCCR_ORGN_MASK U(0x3) +#define SET_GPCCR_ORGN(x) (((x) & GPCCR_ORGN_MASK) << GPCCR_ORGN_SHIFT) + +typedef enum { + GPCCR_ORGN_NC = U(0x0), + GPCCR_ORGN_WB_RA_WA = U(0x1), + GPCCR_ORGN_WT_RA_NWA = U(0x2), + GPCCR_ORGN_WB_RA_NWA = U(0x3) +} gpccr_orgn_e; + +/* GPT fetch inner cacheability attribute bit definitions */ +#define GPCCR_IRGN_SHIFT U(8) +#define GPCCR_IRGN_MASK U(0x3) +#define SET_GPCCR_IRGN(x) (((x) & GPCCR_IRGN_MASK) << GPCCR_IRGN_SHIFT) + +typedef enum { + GPCCR_IRGN_NC = U(0x0), + GPCCR_IRGN_WB_RA_WA = U(0x1), + GPCCR_IRGN_WT_RA_NWA = U(0x2), + GPCCR_IRGN_WB_RA_NWA = U(0x3) +} gpccr_irgn_e; + +/* Protected physical address size bit definitions */ +#define GPCCR_PPS_SHIFT U(0) +#define GPCCR_PPS_MASK U(0x7) +#define SET_GPCCR_PPS(x) (((x) & GPCCR_PPS_MASK) << GPCCR_PPS_SHIFT) + +typedef enum { + GPCCR_PPS_4GB = U(0x0), + GPCCR_PPS_64GB = U(0x1), + GPCCR_PPS_1TB = U(0x2), + GPCCR_PPS_4TB = U(0x3), + GPCCR_PPS_16TB = U(0x4), + GPCCR_PPS_256TB = U(0x5), + GPCCR_PPS_4PB = U(0x6) +} gpccr_pps_e; + +/* Base Address for the GPT bit definitions */ +#define GPTBR_BADDR_SHIFT U(0) +#define GPTBR_BADDR_VAL_SHIFT U(12) +#define GPTBR_BADDR_MASK ULL(0xffffffffff) + +/******************************************************************************/ +/* GPT public APIs */ +/******************************************************************************/ + +/* + * Public API that initializes the entire protected space to GPT_GPI_ANY using + * the L0 tables (block descriptors). Ideally, this function is invoked prior + * to DDR discovery and initialization. The MMU must be initialized before + * calling this function. + * + * Parameters + * pps PPS value to use for table generation + * l0_mem_base Base address of L0 tables in memory. + * l0_mem_size Total size of memory available for L0 tables. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_l0_tables(gpccr_pps_e pps, + uintptr_t l0_mem_base, + size_t l0_mem_size); + +/* + * Public API that carves out PAS regions from the L0 tables and builds any L1 + * tables that are needed. This function ideally is run after DDR discovery and + * initialization. The L0 tables must have already been initialized to GPI_ANY + * when this function is called. + * + * Parameters + * pgs PGS value to use for table generation. + * l1_mem_base Base address of memory used for L1 tables. + * l1_mem_size Total size of memory available for L1 tables. + * *pas_regions Pointer to PAS regions structure array. + * pas_count Total number of PAS regions. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, + uintptr_t l1_mem_base, + size_t l1_mem_size, + pas_region_t *pas_regions, + unsigned int pas_count); + +/* + * Public API to initialize the runtime gpt_config structure based on the values + * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization + * typically happens in a bootloader stage prior to setting up the EL3 runtime + * environment for the granule transition service so this function detects the + * initialization from a previous stage. Granule protection checks must be + * enabled already or this function will return an error. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_runtime_init(void); + +/* + * Public API to enable granule protection checks once the tables have all been + * initialized. This function is called at first initialization and then again + * later during warm boots of CPU cores. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_enable(void); + +/* + * Public API to disable granule protection checks. + */ +void gpt_disable(void); + +/* + * This function is the core of the granule transition service. When a granule + * transition request occurs it is routed to this function where the request is + * validated then fulfilled if possible. + * + * TODO: implement support for transitioning multiple granules at once. + * + * Parameters + * base: Base address of the region to transition, must be aligned to granule + * size. + * size: Size of region to transition, must be aligned to granule size. + * src_sec_state: Security state of the caller. + * target_pas: Target PAS of the specified memory region. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_transition_pas(uint64_t base, + size_t size, + unsigned int src_sec_state, + unsigned int target_pas); + +#endif /* GPT_RME_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index a8b5d26df..1993cb401 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -81,19 +81,19 @@ * - REALM DRAM: Reserved for Realm world if RME is enabled * - AP TZC DRAM: The remaining TZC secured DRAM reserved for AP use * - * RME enabled(64MB) RME not enabled(16MB) - * -------------------- ------------------- - * | | | | - * | AP TZC (~28MB) | | AP TZC (~14MB) | - * -------------------- ------------------- - * | | | | - * | REALM (32MB) | | EL3 TZC (2MB) | - * -------------------- ------------------- - * | | | | - * | EL3 TZC (3MB) | | SCP TZC | - * -------------------- 0xFFFF_FFFF------------------- - * | L1 GPT + SCP TZC | - * | (~1MB) | + * RME enabled(64MB) RME not enabled(16MB) + * -------------------- ------------------- + * | | | | + * | AP TZC (~28MB) | | AP TZC (~14MB) | + * -------------------- ------------------- + * | | | | + * | REALM (32MB) | | EL3 TZC (2MB) | + * -------------------- ------------------- + * | | | | + * | EL3 TZC (3MB) | | SCP TZC | + * -------------------- 0xFFFF_FFFF------------------- + * | L1 GPT + SCP TZC | + * | (~1MB) | * 0xFFFF_FFFF -------------------- */ #if ENABLE_RME @@ -252,56 +252,56 @@ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ GIC_INTR_CFG_EDGE) -#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ - ARM_SHARED_RAM_BASE, \ - ARM_SHARED_RAM_SIZE, \ - MT_DEVICE | MT_RW | EL3_PAS) +#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_DEVICE | MT_RW | EL3_PAS) -#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ - ARM_NS_DRAM1_BASE, \ - ARM_NS_DRAM1_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) +#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ + ARM_NS_DRAM1_BASE, \ + ARM_NS_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) -#define ARM_MAP_DRAM2 MAP_REGION_FLAT( \ - ARM_DRAM2_BASE, \ - ARM_DRAM2_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) +#define ARM_MAP_DRAM2 MAP_REGION_FLAT( \ + ARM_DRAM2_BASE, \ + ARM_DRAM2_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) -#define ARM_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \ - TSP_SEC_MEM_BASE, \ - TSP_SEC_MEM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) +#define ARM_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \ + TSP_SEC_MEM_BASE, \ + TSP_SEC_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) #if ARM_BL31_IN_DRAM -#define ARM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \ - BL31_BASE, \ - PLAT_ARM_MAX_BL31_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) +#define ARM_MAP_BL31_SEC_DRAM MAP_REGION_FLAT( \ + BL31_BASE, \ + PLAT_ARM_MAX_BL31_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) #endif -#define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \ - ARM_EL3_TZC_DRAM1_BASE, \ - ARM_EL3_TZC_DRAM1_SIZE, \ - MT_MEMORY | MT_RW | EL3_PAS) +#define ARM_MAP_EL3_TZC_DRAM MAP_REGION_FLAT( \ + ARM_EL3_TZC_DRAM1_BASE, \ + ARM_EL3_TZC_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | EL3_PAS) #if defined(SPD_spmd) -#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \ - PLAT_ARM_TRUSTED_DRAM_BASE, \ - PLAT_ARM_TRUSTED_DRAM_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) +#define ARM_MAP_TRUSTED_DRAM MAP_REGION_FLAT( \ + PLAT_ARM_TRUSTED_DRAM_BASE, \ + PLAT_ARM_TRUSTED_DRAM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) #endif #if ENABLE_RME -#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \ - PLAT_ARM_RMM_BASE, \ - PLAT_ARM_RMM_SIZE, \ - MT_MEMORY | MT_RW | MT_REALM) +#define ARM_MAP_RMM_DRAM MAP_REGION_FLAT( \ + PLAT_ARM_RMM_BASE, \ + PLAT_ARM_RMM_SIZE, \ + MT_MEMORY | MT_RW | MT_REALM) -#define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \ - ARM_L1_GPT_ADDR_BASE, \ - ARM_L1_GPT_SIZE, \ - MT_MEMORY | MT_RW | EL3_PAS) +#define ARM_MAP_GPT_L1_DRAM MAP_REGION_FLAT( \ + ARM_L1_GPT_ADDR_BASE, \ + ARM_L1_GPT_SIZE, \ + MT_MEMORY | MT_RW | EL3_PAS) #endif /* ENABLE_RME */ diff --git a/include/plat/arm/common/arm_pas_def.h b/include/plat/arm/common/arm_pas_def.h index d268ce613..4fee41b3f 100644 --- a/include/plat/arm/common/arm_pas_def.h +++ b/include/plat/arm/common/arm_pas_def.h @@ -6,6 +6,7 @@ #ifndef ARM_PAS_DEF_H #define ARM_PAS_DEF_H +#include #include /***************************************************************************** @@ -42,12 +43,12 @@ * * - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section. * - ~1MB of L1 GPTs reside at the top of DRAM1 (TZC area). - * - The first 1GB region has GPI_ANY and, therefore, is not protected by + * - The first 1GB region has GPT_GPI_ANY and, therefore, is not protected by * the GPT. * - The DRAM TZC area is split into three regions: the L1 GPT region and - * 3MB of region below that are defined as GPI_ROOT, 32MB Realm region - * below that is defined as GPI_REALM and the rest of it is defined as - * GPI_SECURE. + * 3MB of region below that are defined as GPT_GPI_ROOT, 32MB Realm region + * below that is defined as GPT_GPI_REALM and the rest of it is defined as + * GPT_GPI_SECURE. */ /* TODO: This might not be the best way to map the PAS */ @@ -64,32 +65,30 @@ #define ARM_PAS_3_BASE (ARM_AP_TZC_DRAM1_BASE) #define ARM_PAS_3_SIZE (ARM_AP_TZC_DRAM1_SIZE) -#define ARM_PAS_GPI_ANY MAP_GPT_REGION(ARM_PAS_1_BASE, \ - ARM_PAS_1_SIZE, \ - GPI_ANY) -#define ARM_PAS_KERNEL MAP_GPT_REGION_TBL(ARM_PAS_2_BASE, \ - ARM_PAS_2_SIZE, \ - GPI_NS) +#define ARM_PAS_GPI_ANY MAP_GPT_REGION(ARM_PAS_1_BASE, \ + ARM_PAS_1_SIZE, \ + GPT_GPI_ANY) +#define ARM_PAS_KERNEL GPT_MAP_REGION_GRANULE(ARM_PAS_2_BASE, \ + ARM_PAS_2_SIZE, \ + GPT_GPI_NS) -#define ARM_PAS_TZC MAP_GPT_REGION_TBL(ARM_PAS_3_BASE, \ - ARM_PAS_3_SIZE, \ - GPI_SECURE) +#define ARM_PAS_SECURE GPT_MAP_REGION_GRANULE(ARM_PAS_3_BASE, \ + ARM_PAS_3_SIZE, \ + GPT_GPI_SECURE) -#define ARM_PAS_REALM MAP_GPT_REGION_TBL(ARM_REALM_BASE, \ - ARM_REALM_SIZE, \ - GPI_REALM) +#define ARM_PAS_REALM GPT_MAP_REGION_GRANULE(ARM_REALM_BASE, \ + ARM_REALM_SIZE, \ + GPT_GPI_REALM) -#define ARM_PAS_EL3_DRAM MAP_GPT_REGION_TBL(ARM_EL3_TZC_DRAM1_BASE, \ - ARM_EL3_TZC_DRAM1_SIZE, \ - GPI_ROOT) +#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \ + ARM_EL3_TZC_DRAM1_SIZE, \ + GPT_GPI_ROOT) -#define ARM_PAS_GPTS MAP_GPT_REGION_TBL(ARM_L1_GPT_ADDR_BASE, \ - ARM_L1_GPT_SIZE, \ - GPI_ROOT) +#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_ADDR_BASE, \ + ARM_L1_GPT_SIZE, \ + GPT_GPI_ROOT) /* GPT Configuration options */ -#define PLATFORM_PGS GPCCR_PGS_4K -#define PLATFORM_PPS GPCCR_PPS_4GB #define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS #endif /* ARM_PAS_DEF_H */ diff --git a/lib/gpt/gpt.mk b/lib/gpt/gpt.mk deleted file mode 100644 index 611e50457..000000000 --- a/lib/gpt/gpt.mk +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2021, Arm Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -GPT_LIB_SRCS := $(addprefix lib/gpt/, \ - gpt_core.c) diff --git a/lib/gpt/gpt_core.c b/lib/gpt/gpt_core.c deleted file mode 100644 index 8a3afd2fa..000000000 --- a/lib/gpt/gpt_core.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#if !ENABLE_RME -#error "ENABLE_RME must be enabled to use the GPT library." -#endif - -typedef struct { - uintptr_t plat_gpt_l0_base; - uintptr_t plat_gpt_l1_base; - size_t plat_gpt_l0_size; - size_t plat_gpt_l1_size; - unsigned int plat_gpt_pps; - unsigned int plat_gpt_pgs; - unsigned int plat_gpt_l0gptsz; -} gpt_config_t; - -gpt_config_t gpt_config; - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) -/* Helper function that cleans the data cache only if it is enabled. */ -static inline - void gpt_clean_dcache_range(uintptr_t addr, size_t size) -{ - if ((read_sctlr_el3() & SCTLR_C_BIT) != 0U) { - clean_dcache_range(addr, size); - } -} - -/* Helper function that invalidates the data cache only if it is enabled. */ -static inline - void gpt_inv_dcache_range(uintptr_t addr, size_t size) -{ - if ((read_sctlr_el3() & SCTLR_C_BIT) != 0U) { - inv_dcache_range(addr, size); - } -} -#endif - -typedef struct l1_gpt_attr_desc { - size_t t_sz; /** Table size */ - size_t g_sz; /** Granularity size */ - unsigned int p_val; /** Associated P value */ -} l1_gpt_attr_desc_t; - -/* - * Lookup table to find out the size in bytes of the L1 tables as well - * as the index mask, given the Width of Physical Granule Size (PGS). - * L1 tables are indexed by PA[29:p+4], being 'p' the width in bits of the - * aforementioned Physical Granule Size. - */ -static const l1_gpt_attr_desc_t l1_gpt_attr_lookup[] = { - [GPCCR_PGS_4K] = {U(1) << U(17), /* 16384B x 64bit entry = 128KB */ - PAGE_SIZE_4KB, /* 4KB Granularity */ - U(12)}, - [GPCCR_PGS_64K] = {U(1) << U(13), /* Table size = 8KB */ - PAGE_SIZE_64KB, /* 64KB Granularity */ - U(16)}, - [GPCCR_PGS_16K] = {U(1) << U(15), /* Table size = 32KB */ - PAGE_SIZE_16KB, /* 16KB Granularity */ - U(14)} -}; - -typedef struct l0_gpt_attr_desc { - size_t sz; - unsigned int t_val_mask; -} l0_gpt_attr_desc_t; - -/* - * Lookup table to find out the size in bytes of the L0 table as well - * as the index mask, given the Protected Physical Address Size (PPS). - * L0 table is indexed by PA[t-1:30], being 't' the size in bits - * of the aforementioned Protected Physical Address Size. - */ -static const l0_gpt_attr_desc_t l0_gpt_attr_lookup[] = { - - [GPCCR_PPS_4GB] = {U(1) << U(5), /* 4 x 64 bit entry = 32 bytes */ - 0x3}, /* Bits[31:30] */ - - [GPCCR_PPS_64GB] = {U(1) << U(9), /* 512 bytes */ - 0x3f}, /* Bits[35:30] */ - - [GPCCR_PPS_1TB] = {U(1) << U(13), /* 8KB */ - 0x3ff}, /* Bits[39:30] */ - - [GPCCR_PPS_4TB] = {U(1) << U(15), /* 32KB */ - 0xfff}, /* Bits[41:30] */ - - [GPCCR_PPS_16TB] = {U(1) << U(17), /* 128KB */ - 0x3fff}, /* Bits[43:30] */ - - [GPCCR_PPS_256TB] = {U(1) << U(21), /* 2MB */ - 0x3ffff}, /* Bits[47:30] */ - - [GPCCR_PPS_4PB] = {U(1) << U(25), /* 32MB */ - 0x3fffff}, /* Bits[51:30] */ - -}; - -static unsigned int get_l1_gpt_index(unsigned int pgs, uintptr_t pa) -{ - unsigned int l1_gpt_arr_idx; - - /* - * Mask top 2 bits to obtain the 30 bits required to - * generate the L1 GPT index - */ - l1_gpt_arr_idx = (unsigned int)(pa & L1_GPT_INDEX_MASK); - - /* Shift by 'p' value + 4 to obtain the index */ - l1_gpt_arr_idx >>= (l1_gpt_attr_lookup[pgs].p_val + 4); - - return l1_gpt_arr_idx; -} - -unsigned int plat_is_my_cpu_primary(void); - -/* The granule partition tables can only be configured on BL2 */ -#ifdef IMAGE_BL2 - -/* Global to keep track of next available index in array of L1 GPTs */ -static unsigned int l1_gpt_mem_avlbl_index; - -static int validate_l0_gpt_params(gpt_init_params_t *params) -{ - /* Only 1GB of address space per L0 entry is allowed */ - if (params->l0gptsz != GPCCR_L0GPTSZ_30BITS) { - WARN("Invalid L0GPTSZ %u.\n", params->l0gptsz); - } - - /* Only 4K granule is supported for now */ - if (params->pgs != GPCCR_PGS_4K) { - WARN("Invalid GPT PGS %u.\n", params->pgs); - return -EINVAL; - } - - /* Only 4GB of protected physical address space is supported for now */ - if (params->pps != GPCCR_PPS_4GB) { - WARN("Invalid GPT PPS %u.\n", params->pps); - return -EINVAL; - } - - /* Check if GPT base address is aligned with the system granule */ - if (!IS_PAGE_ALIGNED(params->l0_mem_base)) { - ERROR("Unaligned L0 GPT base address.\n"); - return -EFAULT; - } - - /* Check if there is enough memory for L0 GPTs */ - if (params->l0_mem_size < l0_gpt_attr_lookup[params->pps].sz) { - ERROR("Inadequate memory for L0 GPTs. "); - ERROR("Expected 0x%lx bytes. Got 0x%lx bytes\n", - l0_gpt_attr_lookup[params->pps].sz, - params->l0_mem_size); - return -ENOMEM; - } - - return 0; -} - -/* - * A L1 GPT is required if any one of the following conditions is true: - * - * - The base address is not 1GB aligned - * - The size of the memory region is not a multiple of 1GB - * - A L1 GPT has been explicitly requested (attrs == PAS_REG_DESC_TYPE_TBL) - * - * This function: - * - iterates over all the PAS regions to determine whether they - * will need a 2 stage look up (and therefore a L1 GPT will be required) or - * if it would be enough with a single level lookup table. - * - Updates the attr field of the PAS regions. - * - Returns the total count of L1 tables needed. - * - * In the future wwe should validate that the PAS range does not exceed the - * configured PPS. (and maybe rename this function as it is validating PAS - * regions). - */ -static unsigned int update_gpt_type(pas_region_t *pas_regions, - unsigned int pas_region_cnt) -{ - unsigned int idx, cnt = 0U; - - for (idx = 0U; idx < pas_region_cnt; idx++) { - if (PAS_REG_DESC_TYPE(pas_regions[idx].attrs) == - PAS_REG_DESC_TYPE_TBL) { - cnt++; - continue; - } - if (!(IS_1GB_ALIGNED(pas_regions[idx].base_pa) && - IS_1GB_ALIGNED(pas_regions[idx].size))) { - - /* Current region will need L1 GPTs. */ - assert(PAS_REG_DESC_TYPE(pas_regions[idx].attrs) - == PAS_REG_DESC_TYPE_ANY); - - pas_regions[idx].attrs = - GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_TBL, - PAS_REG_GPI(pas_regions[idx].attrs)); - cnt++; - continue; - } - - /* The PAS can be mapped on a one stage lookup table */ - assert(PAS_REG_DESC_TYPE(pas_regions[idx].attrs) != - PAS_REG_DESC_TYPE_TBL); - - pas_regions[idx].attrs = GPT_DESC_ATTRS(PAS_REG_DESC_TYPE_BLK, - PAS_REG_GPI(pas_regions[idx].attrs)); - } - - return cnt; -} - -static int validate_l1_gpt_params(gpt_init_params_t *params, - unsigned int l1_gpt_cnt) -{ - size_t l1_gpt_sz, l1_gpt_mem_sz; - - /* Check if the granularity is supported */ - assert(xlat_arch_is_granule_size_supported( - l1_gpt_attr_lookup[params->pgs].g_sz)); - - - /* Check if naturally aligned L1 GPTs can be created */ - l1_gpt_sz = l1_gpt_attr_lookup[params->pgs].g_sz; - if (params->l1_mem_base & (l1_gpt_sz - 1)) { - WARN("Unaligned L1 GPT base address.\n"); - return -EFAULT; - } - - /* Check if there is enough memory for L1 GPTs */ - l1_gpt_mem_sz = l1_gpt_cnt * l1_gpt_sz; - if (params->l1_mem_size < l1_gpt_mem_sz) { - WARN("Inadequate memory for L1 GPTs. "); - WARN("Expected 0x%lx bytes. Got 0x%lx bytes\n", - l1_gpt_mem_sz, params->l1_mem_size); - return -ENOMEM; - } - - INFO("Requested 0x%lx bytes for L1 GPTs.\n", l1_gpt_mem_sz); - return 0; -} - -/* - * Helper function to determine if the end physical address lies in the same GB - * as the current physical address. If true, the end physical address is - * returned else, the start address of the next GB is returned. - */ -static uintptr_t get_l1_gpt_end_pa(uintptr_t cur_pa, uintptr_t end_pa) -{ - uintptr_t cur_gb, end_gb; - - cur_gb = cur_pa >> ONE_GB_SHIFT; - end_gb = end_pa >> ONE_GB_SHIFT; - - assert(cur_gb <= end_gb); - - if (cur_gb == end_gb) { - return end_pa; - } - - return (cur_gb + 1) << ONE_GB_SHIFT; -} - -static void generate_l0_blk_desc(gpt_init_params_t *params, - unsigned int idx) -{ - uint64_t gpt_desc; - uintptr_t end_addr; - unsigned int end_idx, start_idx; - pas_region_t *pas = params->pas_regions + idx; - uint64_t *l0_gpt_arr = (uint64_t *)params->l0_mem_base; - - /* Create the GPT Block descriptor for this PAS region */ - gpt_desc = GPT_BLK_DESC; - gpt_desc |= PAS_REG_GPI(pas->attrs) - << GPT_BLOCK_DESC_GPI_VAL_SHIFT; - - /* Start index of this region in L0 GPTs */ - start_idx = pas->base_pa >> ONE_GB_SHIFT; - - /* - * Determine number of L0 GPT descriptors covered by - * this PAS region and use the count to populate these - * descriptors. - */ - end_addr = pas->base_pa + pas->size; - assert(end_addr \ - <= (ULL(l0_gpt_attr_lookup[params->pps].t_val_mask + 1)) << 30); - end_idx = end_addr >> ONE_GB_SHIFT; - - for (; start_idx < end_idx; start_idx++) { - l0_gpt_arr[start_idx] = gpt_desc; - INFO("L0 entry (BLOCK) index %u [%p]: GPI = 0x%llx (0x%llx)\n", - start_idx, &l0_gpt_arr[start_idx], - (gpt_desc >> GPT_BLOCK_DESC_GPI_VAL_SHIFT) & - GPT_L1_INDEX_MASK, l0_gpt_arr[start_idx]); - } -} - -static void generate_l0_tbl_desc(gpt_init_params_t *params, - unsigned int idx) -{ - uint64_t gpt_desc = 0U, *l1_gpt_arr; - uintptr_t start_pa, end_pa, cur_pa, next_pa; - unsigned int start_idx, l1_gpt_idx; - unsigned int p_val, gran_sz; - pas_region_t *pas = params->pas_regions + idx; - uint64_t *l0_gpt_base = (uint64_t *)params->l0_mem_base; - uint64_t *l1_gpt_base = (uint64_t *)params->l1_mem_base; - - start_pa = pas->base_pa; - end_pa = start_pa + pas->size; - p_val = l1_gpt_attr_lookup[params->pgs].p_val; - gran_sz = 1 << p_val; - - /* - * end_pa cannot be larger than the maximum protected physical memory. - */ - assert(((1ULL<<30) << l0_gpt_attr_lookup[params->pps].t_val_mask) - > end_pa); - - for (cur_pa = start_pa; cur_pa < end_pa;) { - /* - * Determine the PA range that will be covered - * in this loop iteration. - */ - next_pa = get_l1_gpt_end_pa(cur_pa, end_pa); - - INFO("PAS[%u]: start: 0x%lx, end: 0x%lx, next_pa: 0x%lx.\n", - idx, cur_pa, end_pa, next_pa); - - /* Index of this PA in L0 GPTs */ - start_idx = cur_pa >> ONE_GB_SHIFT; - - /* - * If cur_pa is on a 1GB boundary then determine - * the base address of next available L1 GPT - * memory region - */ - if (IS_1GB_ALIGNED(cur_pa)) { - l1_gpt_arr = (uint64_t *)((uint64_t)l1_gpt_base + - (l1_gpt_attr_lookup[params->pgs].t_sz * - l1_gpt_mem_avlbl_index)); - - assert(l1_gpt_arr < - (l1_gpt_base + params->l1_mem_size)); - - /* Create the L0 GPT descriptor for this PAS region */ - gpt_desc = GPT_TBL_DESC | - ((uintptr_t)l1_gpt_arr - & GPT_TBL_DESC_ADDR_MASK); - - l0_gpt_base[start_idx] = gpt_desc; - - /* - * Update index to point to next available L1 - * GPT memory region - */ - l1_gpt_mem_avlbl_index++; - } else { - /* Use the existing L1 GPT */ - l1_gpt_arr = (uint64_t *)(l0_gpt_base[start_idx] - & ~((1U<<12) - 1U)); - } - - INFO("L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%llx)\n", - start_idx, &l0_gpt_base[start_idx], - (unsigned long long)(l1_gpt_arr), - l0_gpt_base[start_idx]); - - /* - * Fill up L1 GPT entries between these two - * addresses. - */ - for (; cur_pa < next_pa; cur_pa += gran_sz) { - unsigned int gpi_idx, gpi_idx_shift; - - /* Obtain index of L1 GPT entry */ - l1_gpt_idx = get_l1_gpt_index(params->pgs, cur_pa); - - /* - * Obtain index of GPI in L1 GPT entry - * (i = PA[p_val+3:p_val]) - */ - gpi_idx = (cur_pa >> p_val) & GPT_L1_INDEX_MASK; - - /* - * Shift by index * 4 to reach correct - * GPI entry in L1 GPT descriptor. - * GPI = gpt_desc[(4*idx)+3:(4*idx)] - */ - gpi_idx_shift = gpi_idx << 2; - - gpt_desc = l1_gpt_arr[l1_gpt_idx]; - - /* Clear existing GPI encoding */ - gpt_desc &= ~(GPT_L1_INDEX_MASK << gpi_idx_shift); - - /* Set the GPI encoding */ - gpt_desc |= ((uint64_t)PAS_REG_GPI(pas->attrs) - << gpi_idx_shift); - - l1_gpt_arr[l1_gpt_idx] = gpt_desc; - - if (gpi_idx == 15U) { - VERBOSE("\tEntry %u [%p] = 0x%llx\n", - l1_gpt_idx, - &l1_gpt_arr[l1_gpt_idx], gpt_desc); - } - } - } -} - -static void create_gpt(gpt_init_params_t *params) -{ - unsigned int idx; - pas_region_t *pas_regions = params->pas_regions; - - INFO("pgs = 0x%x, pps = 0x%x, l0gptsz = 0x%x\n", - params->pgs, params->pps, params->l0gptsz); - INFO("pas_region_cnt = 0x%x L1 base = 0x%lx, L1 sz = 0x%lx\n", - params->pas_count, params->l1_mem_base, params->l1_mem_size); - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_inv_dcache_range(params->l0_mem_base, params->l0_mem_size); - gpt_inv_dcache_range(params->l1_mem_base, params->l1_mem_size); -#endif - - for (idx = 0U; idx < params->pas_count; idx++) { - - INFO("PAS[%u]: base 0x%llx, sz 0x%lx, GPI 0x%x, type 0x%x\n", - idx, pas_regions[idx].base_pa, pas_regions[idx].size, - PAS_REG_GPI(pas_regions[idx].attrs), - PAS_REG_DESC_TYPE(pas_regions[idx].attrs)); - - /* Check if a block or table descriptor is required */ - if (PAS_REG_DESC_TYPE(pas_regions[idx].attrs) == - PAS_REG_DESC_TYPE_BLK) { - generate_l0_blk_desc(params, idx); - - } else { - generate_l0_tbl_desc(params, idx); - } - } - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_clean_dcache_range(params->l0_mem_base, params->l0_mem_size); - gpt_clean_dcache_range(params->l1_mem_base, params->l1_mem_size); -#endif - - /* Make sure that all the entries are written to the memory. */ - dsbishst(); -} - -#endif /* IMAGE_BL2 */ - -int gpt_init(gpt_init_params_t *params) -{ -#ifdef IMAGE_BL2 - unsigned int l1_gpt_cnt; - int ret; -#endif - /* Validate arguments */ - assert(params != NULL); - assert(params->pgs <= GPCCR_PGS_16K); - assert(params->pps <= GPCCR_PPS_4PB); - assert(params->l0_mem_base != (uintptr_t)0); - assert(params->l0_mem_size > 0U); - assert(params->l1_mem_base != (uintptr_t)0); - assert(params->l1_mem_size > 0U); - -#ifdef IMAGE_BL2 - /* - * The Granule Protection Tables are initialised only in BL2. - * BL31 is not allowed to initialise them again in case - * these are modified by any other image loaded by BL2. - */ - assert(params->pas_regions != NULL); - assert(params->pas_count > 0U); - - ret = validate_l0_gpt_params(params); - if (ret < 0) { - - return ret; - } - - /* Check if L1 GPTs are required and how many. */ - l1_gpt_cnt = update_gpt_type(params->pas_regions, - params->pas_count); - INFO("%u L1 GPTs requested.\n", l1_gpt_cnt); - - if (l1_gpt_cnt > 0U) { - ret = validate_l1_gpt_params(params, l1_gpt_cnt); - if (ret < 0) { - return ret; - } - } - - create_gpt(params); -#else - /* If running in BL31, only primary CPU can initialise GPTs */ - assert(plat_is_my_cpu_primary() == 1U); - - /* - * If the primary CPU is calling this function from BL31 - * we expect that the tables are aready initialised from - * BL2 and GPCCR_EL3 is already configured with - * Granule Protection Check Enable bit set. - */ - assert((read_gpccr_el3() & GPCCR_GPC_BIT) != 0U); -#endif /* IMAGE_BL2 */ - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_inv_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); -#endif - gpt_config.plat_gpt_l0_base = params->l0_mem_base; - gpt_config.plat_gpt_l1_base = params->l1_mem_base; - gpt_config.plat_gpt_l0_size = params->l0_mem_size; - gpt_config.plat_gpt_l1_size = params->l1_mem_size; - - /* Backup the parameters used to configure GPCCR_EL3 on every PE. */ - gpt_config.plat_gpt_pgs = params->pgs; - gpt_config.plat_gpt_pps = params->pps; - gpt_config.plat_gpt_l0gptsz = params->l0gptsz; - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_clean_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); -#endif - - return 0; -} - -void gpt_enable(void) -{ - u_register_t gpccr_el3; - - /* Invalidate any stale TLB entries */ - tlbipaallos(); - -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_inv_dcache_range((uintptr_t)&gpt_config, sizeof(gpt_config)); -#endif - -#ifdef IMAGE_BL2 - /* - * Granule tables must be initialised before enabling - * granule protection. - */ - assert(gpt_config.plat_gpt_l0_base != (uintptr_t)NULL); -#endif - write_gptbr_el3(gpt_config.plat_gpt_l0_base >> GPTBR_BADDR_VAL_SHIFT); - - /* GPCCR_EL3.L0GPTSZ */ - gpccr_el3 = SET_GPCCR_L0GPTSZ(gpt_config.plat_gpt_l0gptsz); - - /* GPCCR_EL3.PPS */ - gpccr_el3 |= SET_GPCCR_PPS(gpt_config.plat_gpt_pps); - - /* GPCCR_EL3.PGS */ - gpccr_el3 |= SET_GPCCR_PGS(gpt_config.plat_gpt_pgs); - - /* Set shareability attribute to Outher Shareable */ - gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_OS); - - /* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */ - gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA); - gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA); - - /* Enable GPT */ - gpccr_el3 |= GPCCR_GPC_BIT; - - write_gpccr_el3(gpccr_el3); - dsbsy(); - - VERBOSE("Granule Protection Checks enabled\n"); -} - -void gpt_disable(void) -{ - u_register_t gpccr_el3 = read_gpccr_el3(); - - write_gpccr_el3(gpccr_el3 &= ~GPCCR_GPC_BIT); - dsbsy(); -} - -#ifdef IMAGE_BL31 - -/* - * Each L1 descriptor is protected by 1 spinlock. The number of descriptors is - * equal to the size of the total protected memory area divided by the size of - * protected memory area covered by each descriptor. - * - * The size of memory covered by each descriptor is the 'size of the granule' x - * 'number of granules' in a descriptor. The former is PLAT_ARM_GPT_PGS and - * latter is always 16. - */ -static spinlock_t gpt_lock; - -static unsigned int get_l0_gpt_index(unsigned int pps, uint64_t pa) -{ - unsigned int idx; - - /* Get the index into the L0 table */ - idx = pa >> ONE_GB_SHIFT; - - /* Check if the pa lies within the PPS */ - if (idx & ~(l0_gpt_attr_lookup[pps].t_val_mask)) { - WARN("Invalid address 0x%llx.\n", pa); - return -EINVAL; - } - - return idx; -} - -int gpt_transition_pas(uint64_t pa, - unsigned int src_sec_state, - unsigned int target_pas) -{ - int idx; - unsigned int idx_shift; - unsigned int gpi; - uint64_t gpt_l1_desc; - uint64_t *gpt_l1_addr, *gpt_addr; - - /* - * Check if caller is allowed to transition the granule's PAS. - * - * - Secure world caller can only request S <-> NS transitions on a - * granule that is already in either S or NS PAS. - * - * - Realm world caller can only request R <-> NS transitions on a - * granule that is already in either R or NS PAS. - */ - if (src_sec_state == SMC_FROM_REALM) { - if ((target_pas != GPI_REALM) && (target_pas != GPI_NS)) { - WARN("Invalid caller (%s) and PAS (%d) combination.\n", - "realm world", target_pas); - return -EINVAL; - } - } else if (src_sec_state == SMC_FROM_SECURE) { - if ((target_pas != GPI_SECURE) && (target_pas != GPI_NS)) { - WARN("Invalid caller (%s) and PAS (%d) combination.\n", - "secure world", target_pas); - return -EINVAL; - } - } else { - WARN("Invalid caller security state 0x%x\n", src_sec_state); - return -EINVAL; - } - - /* Obtain the L0 GPT address. */ - gpt_addr = (uint64_t *)gpt_config.plat_gpt_l0_base; - - /* Validate physical address and obtain index into L0 GPT table */ - idx = get_l0_gpt_index(gpt_config.plat_gpt_pps, pa); - if (idx < 0U) { - return idx; - } - - VERBOSE("PA 0x%llx, L0 base addr 0x%llx, L0 index %u\n", - pa, (uint64_t)gpt_addr, idx); - - /* Obtain the L0 descriptor */ - gpt_l1_desc = gpt_addr[idx]; - - /* - * Check if it is a table descriptor. Granule transition only applies to - * memory ranges for which L1 tables were created at boot time. So there - * is no possibility of splitting and coalescing tables. - */ - if ((gpt_l1_desc & GPT_L1_INDEX_MASK) != GPT_TBL_DESC) { - WARN("Invalid address 0x%llx.\n", pa); - return -EPERM; - } - - /* Obtain the L1 table address from L0 descriptor. */ - gpt_l1_addr = (uint64_t *)(gpt_l1_desc & ~(0xFFF)); - - /* Obtain the index into the L1 table */ - idx = get_l1_gpt_index(gpt_config.plat_gpt_pgs, pa); - - VERBOSE("L1 table base addr 0x%llx, L1 table index %u\n", (uint64_t)gpt_l1_addr, idx); - - /* Lock access to the granule */ - spin_lock(&gpt_lock); - - /* Obtain the L1 descriptor */ - gpt_l1_desc = gpt_l1_addr[idx]; - - /* Obtain the shift for GPI in L1 GPT entry */ - idx_shift = (pa >> 12) & GPT_L1_INDEX_MASK; - idx_shift <<= 2; - - /* Obtain the current GPI encoding for this PA */ - gpi = (gpt_l1_desc >> idx_shift) & GPT_L1_INDEX_MASK; - - if (src_sec_state == SMC_FROM_REALM) { - /* - * Realm world is only allowed to transition a NS or Realm world - * granule. - */ - if ((gpi != GPI_REALM) && (gpi != GPI_NS)) { - WARN("Invalid transition request from %s.\n", - "realm world"); - spin_unlock(&gpt_lock); - return -EPERM; - } - } else if (src_sec_state == SMC_FROM_SECURE) { - /* - * Secure world is only allowed to transition a NS or Secure world - * granule. - */ - if ((gpi != GPI_SECURE) && (gpi != GPI_NS)) { - WARN("Invalid transition request from %s.\n", - "secure world"); - spin_unlock(&gpt_lock); - return -EPERM; - } - } - /* We don't need an else here since we already handle that above. */ - - VERBOSE("L1 table desc 0x%llx before mod \n", gpt_l1_desc); - - /* Clear existing GPI encoding */ - gpt_l1_desc &= ~(GPT_L1_INDEX_MASK << idx_shift); - - /* Transition the granule to the new PAS */ - gpt_l1_desc |= ((uint64_t)target_pas << idx_shift); - - /* Update the L1 GPT entry */ - gpt_l1_addr[idx] = gpt_l1_desc; - - VERBOSE("L1 table desc 0x%llx after mod \n", gpt_l1_desc); - - /* Make sure change is propagated to other CPUs. */ -#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY) - gpt_clean_dcache_range((uintptr_t)&gpt_addr[idx], sizeof(uint64_t)); -#endif - - gpt_tlbi_by_pa(pa, PAGE_SIZE_4KB); - - /* Make sure that all the entries are written to the memory. */ - dsbishst(); - - /* Unlock access to the granule */ - spin_unlock(&gpt_lock); - - return 0; -} - -#endif /* IMAGE_BL31 */ diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c new file mode 100644 index 000000000..1f90e64cf --- /dev/null +++ b/lib/gpt_rme/gpt_rme.c @@ -0,0 +1,1112 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include +#include +#include "gpt_rme_private.h" +#include +#include +#include +#include + +#if !ENABLE_RME +#error "ENABLE_RME must be enabled to use the GPT library." +#endif + +/* + * Lookup T from PPS + * + * PPS Size T + * 0b000 4GB 32 + * 0b001 64GB 36 + * 0b010 1TB 40 + * 0b011 4TB 42 + * 0b100 16TB 44 + * 0b101 256TB 48 + * 0b110 4PB 52 + * + * See section 15.1.27 of the RME specification. + */ +static const gpt_t_val_e gpt_t_lookup[] = {PPS_4GB_T, PPS_64GB_T, + PPS_1TB_T, PPS_4TB_T, + PPS_16TB_T, PPS_256TB_T, + PPS_4PB_T}; + +/* + * Lookup P from PGS + * + * PGS Size P + * 0b00 4KB 12 + * 0b10 16KB 14 + * 0b01 64KB 16 + * + * Note that pgs=0b10 is 16KB and pgs=0b01 is 64KB, this is not a typo. + * + * See section 15.1.27 of the RME specification. + */ +static const gpt_p_val_e gpt_p_lookup[] = {PGS_4KB_P, PGS_64KB_P, PGS_16KB_P}; + +/* + * This structure contains GPT configuration data. + */ +typedef struct { + uintptr_t plat_gpt_l0_base; + gpccr_pps_e pps; + gpt_t_val_e t; + gpccr_pgs_e pgs; + gpt_p_val_e p; +} gpt_config_t; + +static gpt_config_t gpt_config; + +/* These variables are used during initialization of the L1 tables. */ +static unsigned int gpt_next_l1_tbl_idx; +static uintptr_t gpt_l1_tbl; + +/* + * This function checks to see if a GPI value is valid. + * + * These are valid GPI values. + * GPT_GPI_NO_ACCESS U(0x0) + * GPT_GPI_SECURE U(0x8) + * GPT_GPI_NS U(0x9) + * GPT_GPI_ROOT U(0xA) + * GPT_GPI_REALM U(0xB) + * GPT_GPI_ANY U(0xF) + * + * Parameters + * gpi GPI to check for validity. + * + * Return + * true for a valid GPI, false for an invalid one. + */ +static bool gpt_is_gpi_valid(unsigned int gpi) +{ + if ((gpi == GPT_GPI_NO_ACCESS) || (gpi == GPT_GPI_ANY) || + ((gpi >= GPT_GPI_SECURE) && (gpi <= GPT_GPI_REALM))) { + return true; + } else { + return false; + } +} + +/* + * This function checks to see if two PAS regions overlap. + * + * Parameters + * base_1: base address of first PAS + * size_1: size of first PAS + * base_2: base address of second PAS + * size_2: size of second PAS + * + * Return + * True if PAS regions overlap, false if they do not. + */ +static bool gpt_check_pas_overlap(uintptr_t base_1, size_t size_1, + uintptr_t base_2, size_t size_2) +{ + if (((base_1 + size_1) > base_2) && ((base_2 + size_2) > base_1)) { + return true; + } else { + return false; + } +} + +/* + * This helper function checks to see if a PAS region from index 0 to + * (pas_idx - 1) occupies the L0 region at index l0_idx in the L0 table. + * + * Parameters + * l0_idx: Index of the L0 entry to check + * pas_regions: PAS region array + * pas_idx: Upper bound of the PAS array index. + * + * Return + * True if a PAS region occupies the L0 region in question, false if not. + */ +static bool gpt_does_previous_pas_exist_here(unsigned int l0_idx, + pas_region_t *pas_regions, + unsigned int pas_idx) +{ + /* Iterate over PAS regions up to pas_idx. */ + for (unsigned int i = 0U; i < pas_idx; i++) { + if (gpt_check_pas_overlap((GPT_L0GPTSZ_ACTUAL_SIZE * l0_idx), + GPT_L0GPTSZ_ACTUAL_SIZE, + pas_regions[i].base_pa, pas_regions[i].size)) { + return true; + } + } + return false; +} + +/* + * This function iterates over all of the PAS regions and checks them to ensure + * proper alignment of base and size, that the GPI is valid, and that no regions + * overlap. As a part of the overlap checks, this function checks existing L0 + * mappings against the new PAS regions in the event that gpt_init_pas_l1_tables + * is called multiple times to place L1 tables in different areas of memory. It + * also counts the number of L1 tables needed and returns it on success. + * + * Parameters + * *pas_regions Pointer to array of PAS region structures. + * pas_region_cnt Total number of PAS regions in the array. + * + * Return + * Negative Linux error code in the event of a failure, number of L1 regions + * required when successful. + */ +static int gpt_validate_pas_mappings(pas_region_t *pas_regions, + unsigned int pas_region_cnt) +{ + unsigned int idx; + unsigned int l1_cnt = 0U; + unsigned int pas_l1_cnt; + uint64_t *l0_desc = (uint64_t *)gpt_config.plat_gpt_l0_base; + + assert(pas_regions != NULL); + assert(pas_region_cnt != 0U); + + for (idx = 0U; idx < pas_region_cnt; idx++) { + /* Check for arithmetic overflow in region. */ + if ((ULONG_MAX - pas_regions[idx].base_pa) < + pas_regions[idx].size) { + ERROR("[GPT] Address overflow in PAS[%u]!\n", idx); + return -EOVERFLOW; + } + + /* Initial checks for PAS validity. */ + if (((pas_regions[idx].base_pa + pas_regions[idx].size) > + GPT_PPS_ACTUAL_SIZE(gpt_config.t)) || + !gpt_is_gpi_valid(GPT_PAS_ATTR_GPI(pas_regions[idx].attrs))) { + ERROR("[GPT] PAS[%u] is invalid!\n", idx); + return -EFAULT; + } + + /* + * Make sure this PAS does not overlap with another one. We + * start from idx + 1 instead of 0 since prior PAS mappings will + * have already checked themselves against this one. + */ + for (unsigned int i = idx + 1; i < pas_region_cnt; i++) { + if (gpt_check_pas_overlap(pas_regions[idx].base_pa, + pas_regions[idx].size, + pas_regions[i].base_pa, + pas_regions[i].size)) { + ERROR("[GPT] PAS[%u] overlaps with PAS[%u]\n", + i, idx); + return -EFAULT; + } + } + + /* + * Since this function can be called multiple times with + * separate L1 tables we need to check the existing L0 mapping + * to see if this PAS would fall into one that has already been + * initialized. + */ + for (unsigned int i = GPT_L0_IDX(pas_regions[idx].base_pa); + i <= GPT_L0_IDX(pas_regions[idx].base_pa + pas_regions[idx].size - 1); + i++) { + if ((GPT_L0_TYPE(l0_desc[i]) == GPT_L0_TYPE_BLK_DESC) && + (GPT_L0_BLKD_GPI(l0_desc[i]) == GPT_GPI_ANY)) { + /* This descriptor is unused so continue. */ + continue; + } + + /* + * This descriptor has been initialized in a previous + * call to this function so cannot be initialized again. + */ + ERROR("[GPT] PAS[%u] overlaps with previous L0[%d]!\n", + idx, i); + return -EFAULT; + } + + /* Check for block mapping (L0) type. */ + if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) == + GPT_PAS_ATTR_MAP_TYPE_BLOCK) { + /* Make sure base and size are block-aligned. */ + if (!GPT_IS_L0_ALIGNED(pas_regions[idx].base_pa) || + !GPT_IS_L0_ALIGNED(pas_regions[idx].size)) { + ERROR("[GPT] PAS[%u] is not block-aligned!\n", + idx); + return -EFAULT; + } + + continue; + } + + /* Check for granule mapping (L1) type. */ + if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) == + GPT_PAS_ATTR_MAP_TYPE_GRANULE) { + /* Make sure base and size are granule-aligned. */ + if (!GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].base_pa) || + !GPT_IS_L1_ALIGNED(gpt_config.p, pas_regions[idx].size)) { + ERROR("[GPT] PAS[%u] is not granule-aligned!\n", + idx); + return -EFAULT; + } + + /* Find how many L1 tables this PAS occupies. */ + pas_l1_cnt = (GPT_L0_IDX(pas_regions[idx].base_pa + + pas_regions[idx].size - 1) - + GPT_L0_IDX(pas_regions[idx].base_pa) + 1); + + /* + * This creates a situation where, if multiple PAS + * regions occupy the same table descriptor, we can get + * an artificially high total L1 table count. The way we + * handle this is by checking each PAS against those + * before it in the array, and if they both occupy the + * same PAS we subtract from pas_l1_cnt and only the + * first PAS in the array gets to count it. + */ + + /* + * If L1 count is greater than 1 we know the start and + * end PAs are in different L0 regions so we must check + * both for overlap against other PAS. + */ + if (pas_l1_cnt > 1) { + if (gpt_does_previous_pas_exist_here( + GPT_L0_IDX(pas_regions[idx].base_pa + + pas_regions[idx].size - 1), + pas_regions, idx)) { + pas_l1_cnt = pas_l1_cnt - 1; + } + } + + if (gpt_does_previous_pas_exist_here( + GPT_L0_IDX(pas_regions[idx].base_pa), + pas_regions, idx)) { + pas_l1_cnt = pas_l1_cnt - 1; + } + + l1_cnt += pas_l1_cnt; + continue; + } + + /* If execution reaches this point, mapping type is invalid. */ + ERROR("[GPT] PAS[%u] has invalid mapping type 0x%x.\n", idx, + GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs)); + return -EINVAL; + } + + return l1_cnt; +} + +/* + * This function validates L0 initialization parameters. + * + * Parameters + * l0_mem_base Base address of memory used for L0 tables. + * l1_mem_size Size of memory available for L0 tables. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +static int gpt_validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base, + size_t l0_mem_size) +{ + size_t l0_alignment; + + /* + * Make sure PPS is valid and then store it since macros need this value + * to work. + */ + if (pps > GPT_PPS_MAX) { + ERROR("[GPT] Invalid PPS: 0x%x\n", pps); + return -EINVAL; + } + gpt_config.pps = pps; + gpt_config.t = gpt_t_lookup[pps]; + + /* Alignment must be the greater of 4k or l0 table size. */ + l0_alignment = PAGE_SIZE_4KB; + if (l0_alignment < GPT_L0_TABLE_SIZE(gpt_config.t)) { + l0_alignment = GPT_L0_TABLE_SIZE(gpt_config.t); + } + + /* Check base address. */ + if ((l0_mem_base == 0U) || ((l0_mem_base & (l0_alignment - 1)) != 0U)) { + ERROR("[GPT] Invalid L0 base address: 0x%lx\n", l0_mem_base); + return -EFAULT; + } + + /* Check size. */ + if (l0_mem_size < GPT_L0_TABLE_SIZE(gpt_config.t)) { + ERROR("[GPT] Inadequate L0 memory: need 0x%lx, have 0x%lx)\n", + GPT_L0_TABLE_SIZE(gpt_config.t), + l0_mem_size); + return -ENOMEM; + } + + return 0; +} + +/* + * In the event that L1 tables are needed, this function validates + * the L1 table generation parameters. + * + * Parameters + * l1_mem_base Base address of memory used for L1 table allocation. + * l1_mem_size Total size of memory available for L1 tables. + * l1_gpt_cnt Number of L1 tables needed. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +static int gpt_validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size, + unsigned int l1_gpt_cnt) +{ + size_t l1_gpt_mem_sz; + + /* Check if the granularity is supported */ + if (!xlat_arch_is_granule_size_supported( + GPT_PGS_ACTUAL_SIZE(gpt_config.p))) { + return -EPERM; + } + + /* Make sure L1 tables are aligned to their size. */ + if ((l1_mem_base & (GPT_L1_TABLE_SIZE(gpt_config.p) - 1)) != 0U) { + ERROR("[GPT] Unaligned L1 GPT base address: 0x%lx\n", + l1_mem_base); + return -EFAULT; + } + + /* Get total memory needed for L1 tables. */ + l1_gpt_mem_sz = l1_gpt_cnt * GPT_L1_TABLE_SIZE(gpt_config.p); + + /* Check for overflow. */ + if ((l1_gpt_mem_sz / GPT_L1_TABLE_SIZE(gpt_config.p)) != l1_gpt_cnt) { + ERROR("[GPT] Overflow calculating L1 memory size.\n"); + return -ENOMEM; + } + + /* Make sure enough space was supplied. */ + if (l1_mem_size < l1_gpt_mem_sz) { + ERROR("[GPT] Inadequate memory for L1 GPTs. "); + ERROR(" Expected 0x%lx bytes. Got 0x%lx bytes\n", + l1_gpt_mem_sz, l1_mem_size); + return -ENOMEM; + } + + VERBOSE("[GPT] Requested 0x%lx bytes for L1 GPTs.\n", l1_gpt_mem_sz); + return 0; +} + +/* + * This function initializes L0 block descriptors (regions that cannot be + * transitioned at the granule level) according to the provided PAS. + * + * Parameters + * *pas Pointer to the structure defining the PAS region to + * initialize. + */ +static void gpt_generate_l0_blk_desc(pas_region_t *pas) +{ + uint64_t gpt_desc; + unsigned int end_idx; + unsigned int idx; + uint64_t *l0_gpt_arr; + + assert(gpt_config.plat_gpt_l0_base != 0U); + assert(pas != NULL); + + /* + * Checking of PAS parameters has already been done in + * gpt_validate_pas_mappings so no need to check the same things again. + */ + + l0_gpt_arr = (uint64_t *)gpt_config.plat_gpt_l0_base; + + /* Create the GPT Block descriptor for this PAS region */ + gpt_desc = GPT_L0_BLK_DESC(GPT_PAS_ATTR_GPI(pas->attrs)); + + /* Start index of this region in L0 GPTs */ + idx = pas->base_pa >> GPT_L0_IDX_SHIFT; + + /* + * Determine number of L0 GPT descriptors covered by + * this PAS region and use the count to populate these + * descriptors. + */ + end_idx = (pas->base_pa + pas->size) >> GPT_L0_IDX_SHIFT; + + /* Generate the needed block descriptors. */ + for (; idx < end_idx; idx++) { + l0_gpt_arr[idx] = gpt_desc; + VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%llx (0x%llx)\n", + idx, &l0_gpt_arr[idx], + (gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) & + GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]); + } +} + +/* + * Helper function to determine if the end physical address lies in the same L0 + * region as the current physical address. If true, the end physical address is + * returned else, the start address of the next region is returned. + * + * Parameters + * cur_pa Physical address of the current PA in the loop through + * the range. + * end_pa Physical address of the end PA in a PAS range. + * + * Return + * The PA of the end of the current range. + */ +static uintptr_t gpt_get_l1_end_pa(uintptr_t cur_pa, uintptr_t end_pa) +{ + uintptr_t cur_idx; + uintptr_t end_idx; + + cur_idx = cur_pa >> GPT_L0_IDX_SHIFT; + end_idx = end_pa >> GPT_L0_IDX_SHIFT; + + assert(cur_idx <= end_idx); + + if (cur_idx == end_idx) { + return end_pa; + } + + return (cur_idx + 1U) << GPT_L0_IDX_SHIFT; +} + +/* + * Helper function to fill out GPI entries in a single L1 table. This function + * fills out entire L1 descriptors at a time to save memory writes. + * + * Parameters + * gpi GPI to set this range to + * l1 Pointer to L1 table to fill out + * first Address of first granule in range. + * last Address of last granule in range (inclusive). + */ +static void gpt_fill_l1_tbl(uint64_t gpi, uint64_t *l1, uintptr_t first, + uintptr_t last) +{ + uint64_t gpi_field = GPT_BUILD_L1_DESC(gpi); + uint64_t gpi_mask = 0xFFFFFFFFFFFFFFFF; + + assert(first <= last); + assert((first & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U); + assert((last & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) == 0U); + assert(GPT_L0_IDX(first) == GPT_L0_IDX(last)); + assert(l1 != NULL); + + /* Shift the mask if we're starting in the middle of an L1 entry. */ + gpi_mask = gpi_mask << (GPT_L1_GPI_IDX(gpt_config.p, first) << 2); + + /* Fill out each L1 entry for this region. */ + for (unsigned int i = GPT_L1_IDX(gpt_config.p, first); + i <= GPT_L1_IDX(gpt_config.p, last); i++) { + /* Account for stopping in the middle of an L1 entry. */ + if (i == GPT_L1_IDX(gpt_config.p, last)) { + gpi_mask &= (gpi_mask >> ((15 - + GPT_L1_GPI_IDX(gpt_config.p, last)) << 2)); + } + + /* Write GPI values. */ + assert((l1[i] & gpi_mask) == + (GPT_BUILD_L1_DESC(GPT_GPI_ANY) & gpi_mask)); + l1[i] = (l1[i] & ~gpi_mask) | (gpi_mask & gpi_field); + + /* Reset mask. */ + gpi_mask = 0xFFFFFFFFFFFFFFFF; + } +} + +/* + * This function finds the next available unused L1 table and initializes all + * granules descriptor entries to GPI_ANY. This ensures that there are no chunks + * of GPI_NO_ACCESS (0b0000) memory floating around in the system in the + * event that a PAS region stops midway through an L1 table, thus guaranteeing + * that all memory not explicitly assigned is GPI_ANY. This function does not + * check for overflow conditions, that should be done by the caller. + * + * Return + * Pointer to the next available L1 table. + */ +static uint64_t *gpt_get_new_l1_tbl(void) +{ + /* Retrieve the next L1 table. */ + uint64_t *l1 = (uint64_t *)((uint64_t)(gpt_l1_tbl) + + (GPT_L1_TABLE_SIZE(gpt_config.p) * + gpt_next_l1_tbl_idx)); + + /* Increment L1 counter. */ + gpt_next_l1_tbl_idx++; + + /* Initialize all GPIs to GPT_GPI_ANY */ + for (unsigned int i = 0U; i < GPT_L1_ENTRY_COUNT(gpt_config.p); i++) { + l1[i] = GPT_BUILD_L1_DESC(GPT_GPI_ANY); + } + + return l1; +} + +/* + * When L1 tables are needed, this function creates the necessary L0 table + * descriptors and fills out the L1 table entries according to the supplied + * PAS range. + * + * Parameters + * *pas Pointer to the structure defining the PAS region. + */ +static void gpt_generate_l0_tbl_desc(pas_region_t *pas) +{ + uintptr_t end_pa; + uintptr_t cur_pa; + uintptr_t last_gran_pa; + uint64_t *l0_gpt_base; + uint64_t *l1_gpt_arr; + unsigned int l0_idx; + + assert(gpt_config.plat_gpt_l0_base != 0U); + assert(pas != NULL); + + /* + * Checking of PAS parameters has already been done in + * gpt_validate_pas_mappings so no need to check the same things again. + */ + + end_pa = pas->base_pa + pas->size; + l0_gpt_base = (uint64_t *)gpt_config.plat_gpt_l0_base; + + /* We start working from the granule at base PA */ + cur_pa = pas->base_pa; + + /* Iterate over each L0 region in this memory range. */ + for (l0_idx = GPT_L0_IDX(pas->base_pa); + l0_idx <= GPT_L0_IDX(end_pa - 1U); + l0_idx++) { + + /* + * See if the L0 entry is already a table descriptor or if we + * need to create one. + */ + if (GPT_L0_TYPE(l0_gpt_base[l0_idx]) == GPT_L0_TYPE_TBL_DESC) { + /* Get the L1 array from the L0 entry. */ + l1_gpt_arr = GPT_L0_TBLD_ADDR(l0_gpt_base[l0_idx]); + } else { + /* Get a new L1 table from the L1 memory space. */ + l1_gpt_arr = gpt_get_new_l1_tbl(); + + /* Fill out the L0 descriptor and flush it. */ + l0_gpt_base[l0_idx] = GPT_L0_TBL_DESC(l1_gpt_arr); + } + + VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%llx)\n", + l0_idx, &l0_gpt_base[l0_idx], + (unsigned long long)(l1_gpt_arr), + l0_gpt_base[l0_idx]); + + /* + * Determine the PA of the last granule in this L0 descriptor. + */ + last_gran_pa = gpt_get_l1_end_pa(cur_pa, end_pa) - + GPT_PGS_ACTUAL_SIZE(gpt_config.p); + + /* + * Fill up L1 GPT entries between these two addresses. This + * function needs the addresses of the first granule and last + * granule in the range. + */ + gpt_fill_l1_tbl(GPT_PAS_ATTR_GPI(pas->attrs), l1_gpt_arr, + cur_pa, last_gran_pa); + + /* Advance cur_pa to first granule in next L0 region. */ + cur_pa = gpt_get_l1_end_pa(cur_pa, end_pa); + } +} + +/* + * This function flushes a range of L0 descriptors used by a given PAS region + * array. There is a chance that some unmodified L0 descriptors would be flushed + * in the case that there are "holes" in an array of PAS regions but overall + * this should be faster than individually flushing each modified L0 descriptor + * as they are created. + * + * Parameters + * *pas Pointer to an array of PAS regions. + * pas_count Number of entries in the PAS array. + */ +static void flush_l0_for_pas_array(pas_region_t *pas, unsigned int pas_count) +{ + unsigned int idx; + unsigned int start_idx; + unsigned int end_idx; + uint64_t *l0 = (uint64_t *)gpt_config.plat_gpt_l0_base; + + assert(pas != NULL); + assert(pas_count > 0); + + /* Initial start and end values. */ + start_idx = GPT_L0_IDX(pas[0].base_pa); + end_idx = GPT_L0_IDX(pas[0].base_pa + pas[0].size - 1); + + /* Find lowest and highest L0 indices used in this PAS array. */ + for (idx = 1; idx < pas_count; idx++) { + if (GPT_L0_IDX(pas[idx].base_pa) < start_idx) { + start_idx = GPT_L0_IDX(pas[idx].base_pa); + } + if (GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1) > end_idx) { + end_idx = GPT_L0_IDX(pas[idx].base_pa + pas[idx].size - 1); + } + } + + /* + * Flush all covered L0 descriptors, add 1 because we need to include + * the end index value. + */ + flush_dcache_range((uintptr_t)&l0[start_idx], + ((end_idx + 1) - start_idx) * sizeof(uint64_t)); +} + +/* + * Public API to enable granule protection checks once the tables have all been + * initialized. This function is called at first initialization and then again + * later during warm boots of CPU cores. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_enable(void) +{ + u_register_t gpccr_el3; + + /* + * Granule tables must be initialised before enabling + * granule protection. + */ + if (gpt_config.plat_gpt_l0_base == 0U) { + ERROR("[GPT] Tables have not been initialized!\n"); + return -EPERM; + } + + /* Invalidate any stale TLB entries */ + tlbipaallos(); + dsb(); + + /* Write the base address of the L0 tables into GPTBR */ + write_gptbr_el3(((gpt_config.plat_gpt_l0_base >> GPTBR_BADDR_VAL_SHIFT) + >> GPTBR_BADDR_SHIFT) & GPTBR_BADDR_MASK); + + /* GPCCR_EL3.PPS */ + gpccr_el3 = SET_GPCCR_PPS(gpt_config.pps); + + /* GPCCR_EL3.PGS */ + gpccr_el3 |= SET_GPCCR_PGS(gpt_config.pgs); + + /* Set shareability attribute to Outher Shareable */ + gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_OS); + + /* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */ + gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA); + gpccr_el3 |= SET_GPCCR_IRGN(GPCCR_IRGN_WB_RA_WA); + + /* Enable GPT */ + gpccr_el3 |= GPCCR_GPC_BIT; + + /* TODO: Configure GPCCR_EL3_GPCP for Fault control. */ + write_gpccr_el3(gpccr_el3); + tlbipaallos(); + dsb(); + isb(); + + return 0; +} + +/* + * Public API to disable granule protection checks. + */ +void gpt_disable(void) +{ + u_register_t gpccr_el3 = read_gpccr_el3(); + + write_gpccr_el3(gpccr_el3 & ~GPCCR_GPC_BIT); + dsbsy(); + isb(); +} + +/* + * Public API that initializes the entire protected space to GPT_GPI_ANY using + * the L0 tables (block descriptors). Ideally, this function is invoked prior + * to DDR discovery and initialization. The MMU must be initialized before + * calling this function. + * + * Parameters + * pps PPS value to use for table generation + * l0_mem_base Base address of L0 tables in memory. + * l0_mem_size Total size of memory available for L0 tables. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_l0_tables(unsigned int pps, uintptr_t l0_mem_base, + size_t l0_mem_size) +{ + int ret; + uint64_t gpt_desc; + + /* Ensure that MMU and caches are enabled. */ + assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); + + /* Validate other parameters. */ + ret = gpt_validate_l0_params(pps, l0_mem_base, l0_mem_size); + if (ret < 0) { + return ret; + } + + /* Create the descriptor to initialize L0 entries with. */ + gpt_desc = GPT_L0_BLK_DESC(GPT_GPI_ANY); + + /* Iterate through all L0 entries */ + for (unsigned int i = 0U; i < GPT_L0_REGION_COUNT(gpt_config.t); i++) { + ((uint64_t *)l0_mem_base)[i] = gpt_desc; + } + + /* Flush updated L0 tables to memory. */ + flush_dcache_range((uintptr_t)l0_mem_base, + (size_t)GPT_L0_TABLE_SIZE(gpt_config.t)); + + /* Stash the L0 base address once initial setup is complete. */ + gpt_config.plat_gpt_l0_base = l0_mem_base; + + return 0; +} + +/* + * Public API that carves out PAS regions from the L0 tables and builds any L1 + * tables that are needed. This function ideally is run after DDR discovery and + * initialization. The L0 tables must have already been initialized to GPI_ANY + * when this function is called. + * + * This function can be called multiple times with different L1 memory ranges + * and PAS regions if it is desirable to place L1 tables in different locations + * in memory. (ex: you have multiple DDR banks and want to place the L1 tables + * in the DDR bank that they control) + * + * Parameters + * pgs PGS value to use for table generation. + * l1_mem_base Base address of memory used for L1 tables. + * l1_mem_size Total size of memory available for L1 tables. + * *pas_regions Pointer to PAS regions structure array. + * pas_count Total number of PAS regions. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base, + size_t l1_mem_size, pas_region_t *pas_regions, + unsigned int pas_count) +{ + int ret; + int l1_gpt_cnt; + + /* Ensure that MMU and caches are enabled. */ + assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); + + /* PGS is needed for gpt_validate_pas_mappings so check it now. */ + if (pgs > GPT_PGS_MAX) { + ERROR("[GPT] Invalid PGS: 0x%x\n", pgs); + return -EINVAL; + } + gpt_config.pgs = pgs; + gpt_config.p = gpt_p_lookup[pgs]; + + /* Make sure L0 tables have been initialized. */ + if (gpt_config.plat_gpt_l0_base == 0U) { + ERROR("[GPT] L0 tables must be initialized first!\n"); + return -EPERM; + } + + /* Check if L1 GPTs are required and how many. */ + l1_gpt_cnt = gpt_validate_pas_mappings(pas_regions, pas_count); + if (l1_gpt_cnt < 0) { + return l1_gpt_cnt; + } + + VERBOSE("[GPT] %u L1 GPTs requested.\n", l1_gpt_cnt); + + /* If L1 tables are needed then validate the L1 parameters. */ + if (l1_gpt_cnt > 0) { + ret = gpt_validate_l1_params(l1_mem_base, l1_mem_size, + l1_gpt_cnt); + if (ret < 0) { + return ret; + } + + /* Set up parameters for L1 table generation. */ + gpt_l1_tbl = l1_mem_base; + gpt_next_l1_tbl_idx = 0U; + } + + INFO("[GPT] Boot Configuration\n"); + INFO(" PPS/T: 0x%x/%u\n", gpt_config.pps, gpt_config.t); + INFO(" PGS/P: 0x%x/%u\n", gpt_config.pgs, gpt_config.p); + INFO(" L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL); + INFO(" PAS count: 0x%x\n", pas_count); + INFO(" L0 base: 0x%lx\n", gpt_config.plat_gpt_l0_base); + + /* Generate the tables in memory. */ + for (unsigned int idx = 0U; idx < pas_count; idx++) { + INFO("[GPT] PAS[%u]: base 0x%lx, size 0x%lx, GPI 0x%x, type 0x%x\n", + idx, pas_regions[idx].base_pa, pas_regions[idx].size, + GPT_PAS_ATTR_GPI(pas_regions[idx].attrs), + GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs)); + + /* Check if a block or table descriptor is required */ + if (GPT_PAS_ATTR_MAP_TYPE(pas_regions[idx].attrs) == + GPT_PAS_ATTR_MAP_TYPE_BLOCK) { + gpt_generate_l0_blk_desc(&pas_regions[idx]); + + } else { + gpt_generate_l0_tbl_desc(&pas_regions[idx]); + } + } + + /* Flush modified L0 tables. */ + flush_l0_for_pas_array(pas_regions, pas_count); + + /* Flush L1 tables if needed. */ + if (l1_gpt_cnt > 0) { + flush_dcache_range(l1_mem_base, + GPT_L1_TABLE_SIZE(gpt_config.p) * + l1_gpt_cnt); + } + + /* Make sure that all the entries are written to the memory. */ + dsbishst(); + + return 0; +} + +/* + * Public API to initialize the runtime gpt_config structure based on the values + * present in the GPTBR_EL3 and GPCCR_EL3 registers. GPT initialization + * typically happens in a bootloader stage prior to setting up the EL3 runtime + * environment for the granule transition service so this function detects the + * initialization from a previous stage. Granule protection checks must be + * enabled already or this function will return an error. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_runtime_init(void) +{ + u_register_t reg; + + /* Ensure that MMU and caches are enabled. */ + assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); + + /* Ensure GPC are already enabled. */ + if ((read_gpccr_el3() & GPCCR_GPC_BIT) == 0U) { + ERROR("[GPT] Granule protection checks are not enabled!\n"); + return -EPERM; + } + + /* + * Read the L0 table address from GPTBR, we don't need the L1 base + * address since those are included in the L0 tables as needed. + */ + reg = read_gptbr_el3(); + gpt_config.plat_gpt_l0_base = ((reg >> GPTBR_BADDR_SHIFT) & + GPTBR_BADDR_MASK) << + GPTBR_BADDR_VAL_SHIFT; + + /* Read GPCCR to get PGS and PPS values. */ + reg = read_gpccr_el3(); + gpt_config.pps = (reg >> GPCCR_PPS_SHIFT) & GPCCR_PPS_MASK; + gpt_config.t = gpt_t_lookup[gpt_config.pps]; + gpt_config.pgs = (reg >> GPCCR_PGS_SHIFT) & GPCCR_PGS_MASK; + gpt_config.p = gpt_p_lookup[gpt_config.pgs]; + + VERBOSE("[GPT] Runtime Configuration\n"); + VERBOSE(" PPS/T: 0x%x/%u\n", gpt_config.pps, gpt_config.t); + VERBOSE(" PGS/P: 0x%x/%u\n", gpt_config.pgs, gpt_config.p); + VERBOSE(" L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL); + VERBOSE(" L0 base: 0x%lx\n", gpt_config.plat_gpt_l0_base); + + return 0; +} + +/* + * The L1 descriptors are protected by a spinlock to ensure that multiple + * CPUs do not attempt to change the descriptors at once. In the future it + * would be better to have separate spinlocks for each L1 descriptor. + */ +static spinlock_t gpt_lock; + +/* + * Check if caller is allowed to transition a PAS. + * + * - Secure world caller can only request S <-> NS transitions on a + * granule that is already in either S or NS PAS. + * + * - Realm world caller can only request R <-> NS transitions on a + * granule that is already in either R or NS PAS. + * + * Parameters + * src_sec_state Security state of the caller. + * current_gpi Current GPI of the granule. + * target_gpi Requested new GPI for the granule. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +static int gpt_check_transition_gpi(unsigned int src_sec_state, + unsigned int current_gpi, + unsigned int target_gpi) +{ + unsigned int check_gpi; + + /* Cannot transition a granule to the state it is already in. */ + if (current_gpi == target_gpi) { + return -EINVAL; + } + + /* Check security state, only secure and realm can transition. */ + if (src_sec_state == SMC_FROM_REALM) { + check_gpi = GPT_GPI_REALM; + } else if (src_sec_state == SMC_FROM_SECURE) { + check_gpi = GPT_GPI_SECURE; + } else { + return -EINVAL; + } + + /* Make sure security state is allowed to make the transition. */ + if ((target_gpi != check_gpi) && (target_gpi != GPT_GPI_NS)) { + return -EINVAL; + } + if ((current_gpi != check_gpi) && (current_gpi != GPT_GPI_NS)) { + return -EINVAL; + } + + return 0; +} + +/* + * This function is the core of the granule transition service. When a granule + * transition request occurs it is routed to this function where the request is + * validated then fulfilled if possible. + * + * TODO: implement support for transitioning multiple granules at once. + * + * Parameters + * base Base address of the region to transition, must be + * aligned to granule size. + * size Size of region to transition, must be aligned to granule + * size. + * src_sec_state Security state of the caller. + * target_pas Target PAS of the specified memory region. + * + * Return + * Negative Linux error code in the event of a failure, 0 for success. + */ +int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, + unsigned int target_pas) +{ + int idx; + unsigned int gpi_shift; + unsigned int gpi; + uint64_t gpt_l0_desc; + uint64_t gpt_l1_desc; + uint64_t *gpt_l1_addr; + uint64_t *gpt_l0_base; + + /* Ensure that the tables have been set up before taking requests. */ + assert(gpt_config.plat_gpt_l0_base != 0U); + + /* Check for address range overflow. */ + if ((ULONG_MAX - base) < size) { + VERBOSE("[GPT] Transition request address overflow!\n"); + VERBOSE(" Base=0x%llx\n", base); + VERBOSE(" Size=0x%lx\n", size); + return -EINVAL; + } + + /* Make sure base and size are valid. */ + if (((base & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0U) || + ((size & (GPT_PGS_ACTUAL_SIZE(gpt_config.p) - 1)) != 0U) || + (size == 0U) || + ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) { + VERBOSE("[GPT] Invalid granule transition address range!\n"); + VERBOSE(" Base=0x%llx\n", base); + VERBOSE(" Size=0x%lx\n", size); + return -EINVAL; + } + + /* See if this is a single granule transition or a range of granules. */ + if (size != GPT_PGS_ACTUAL_SIZE(gpt_config.p)) { + /* + * TODO: Add support for transitioning multiple granules with a + * single call to this function. + */ + panic(); + } + + /* Get the L0 descriptor and make sure it is for a table. */ + gpt_l0_base = (uint64_t *)gpt_config.plat_gpt_l0_base; + gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)]; + if (GPT_L0_TYPE(gpt_l0_desc) != GPT_L0_TYPE_TBL_DESC) { + VERBOSE("[GPT] Granule is not covered by a table descriptor!\n"); + VERBOSE(" Base=0x%llx\n", base); + return -EINVAL; + } + + /* Get the table index and GPI shift from PA. */ + gpt_l1_addr = GPT_L0_TBLD_ADDR(gpt_l0_desc); + idx = GPT_L1_IDX(gpt_config.p, base); + gpi_shift = GPT_L1_GPI_IDX(gpt_config.p, base) << 2; + + /* + * Access to L1 tables is controlled by a global lock to ensure + * that no more than one CPU is allowed to make changes at any + * given time. + */ + spin_lock(&gpt_lock); + gpt_l1_desc = gpt_l1_addr[idx]; + gpi = (gpt_l1_desc >> gpi_shift) & GPT_L1_GRAN_DESC_GPI_MASK; + + /* Make sure caller state and source/target PAS are allowed. */ + if (gpt_check_transition_gpi(src_sec_state, gpi, target_pas) < 0) { + spin_unlock(&gpt_lock); + VERBOSE("[GPT] Invalid caller state and PAS combo!\n"); + VERBOSE(" Caller: %u, Current GPI: %u, Target GPI: %u\n", + src_sec_state, gpi, target_pas); + return -EPERM; + } + + /* Clear existing GPI encoding and transition granule. */ + gpt_l1_desc &= ~(GPT_L1_GRAN_DESC_GPI_MASK << gpi_shift); + gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift); + gpt_l1_addr[idx] = gpt_l1_desc; + + /* Ensure that the write operation happens before the unlock. */ + dmbishst(); + + /* Unlock access to the L1 tables. */ + spin_unlock(&gpt_lock); + + /* Cache maintenance. */ + clean_dcache_range((uintptr_t)&gpt_l1_addr[idx], + sizeof(uint64_t)); + gpt_tlbi_by_pa(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p)); + dsbishst(); + + VERBOSE("[GPT] Granule 0x%llx, GPI 0x%x->0x%x\n", base, gpi, + target_pas); + + return 0; +} diff --git a/lib/gpt_rme/gpt_rme.mk b/lib/gpt_rme/gpt_rme.mk new file mode 100644 index 000000000..60176f4e1 --- /dev/null +++ b/lib/gpt_rme/gpt_rme.mk @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +GPT_LIB_SRCS := $(addprefix lib/gpt_rme/, \ + gpt_rme.c) diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h new file mode 100644 index 000000000..5770bf7d6 --- /dev/null +++ b/lib/gpt_rme/gpt_rme_private.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GPT_RME_PRIVATE_H +#define GPT_RME_PRIVATE_H + +#include +#include +#include + +/******************************************************************************/ +/* GPT descriptor definitions */ +/******************************************************************************/ + +/* GPT level 0 descriptor bit definitions. */ +#define GPT_L0_TYPE_MASK UL(0xF) +#define GPT_L0_TYPE_SHIFT U(0) + +/* For now, we don't support contiguous descriptors, only table and block. */ +#define GPT_L0_TYPE_TBL_DESC UL(0x3) +#define GPT_L0_TYPE_BLK_DESC UL(0x1) + +#define GPT_L0_TBL_DESC_L1ADDR_MASK UL(0xFFFFFFFFFF) +#define GPT_L0_TBL_DESC_L1ADDR_SHIFT U(12) + +#define GPT_L0_BLK_DESC_GPI_MASK UL(0xF) +#define GPT_L0_BLK_DESC_GPI_SHIFT U(4) + +/* GPT level 1 descriptor bit definitions */ +#define GPT_L1_GRAN_DESC_GPI_MASK UL(0xF) + +/* + * This macro fills out every GPI entry in a granules descriptor to the same + * value. + */ +#define GPT_BUILD_L1_DESC(_gpi) (((uint64_t)(_gpi) << 4*0) | \ + ((uint64_t)(_gpi) << 4*1) | \ + ((uint64_t)(_gpi) << 4*2) | \ + ((uint64_t)(_gpi) << 4*3) | \ + ((uint64_t)(_gpi) << 4*4) | \ + ((uint64_t)(_gpi) << 4*5) | \ + ((uint64_t)(_gpi) << 4*6) | \ + ((uint64_t)(_gpi) << 4*7) | \ + ((uint64_t)(_gpi) << 4*8) | \ + ((uint64_t)(_gpi) << 4*9) | \ + ((uint64_t)(_gpi) << 4*10) | \ + ((uint64_t)(_gpi) << 4*11) | \ + ((uint64_t)(_gpi) << 4*12) | \ + ((uint64_t)(_gpi) << 4*13) | \ + ((uint64_t)(_gpi) << 4*14) | \ + ((uint64_t)(_gpi) << 4*15)) + +/******************************************************************************/ +/* GPT platform configuration */ +/******************************************************************************/ + +/* This value comes from GPCCR_EL3 so no externally supplied definition. */ +#define GPT_L0GPTSZ ((unsigned int)((read_gpccr_el3() >> \ + GPCCR_L0GPTSZ_SHIFT) & GPCCR_L0GPTSZ_MASK)) + +/* The "S" value is directly related to L0GPTSZ */ +#define GPT_S_VAL (GPT_L0GPTSZ + 30U) + +/* + * Map PPS values to T values. + * + * PPS Size T + * 0b000 4GB 32 + * 0b001 64GB 36 + * 0b010 1TB 40 + * 0b011 4TB 42 + * 0b100 16TB 44 + * 0b101 256TB 48 + * 0b110 4PB 52 + * + * See section 15.1.27 of the RME specification. + */ +typedef enum { + PPS_4GB_T = 32U, + PPS_64GB_T = 36U, + PPS_1TB_T = 40U, + PPS_4TB_T = 42U, + PPS_16TB_T = 44U, + PPS_256TB_T = 48U, + PPS_4PB_T = 52U +} gpt_t_val_e; + +/* + * Map PGS values to P values. + * + * PGS Size P + * 0b00 4KB 12 + * 0b10 16KB 14 + * 0b01 64KB 16 + * + * Note that pgs=0b10 is 16KB and pgs=0b01 is 64KB, this is not a typo. + * + * See section 15.1.27 of the RME specification. + */ +typedef enum { + PGS_4KB_P = 12U, + PGS_16KB_P = 14U, + PGS_64KB_P = 16U +} gpt_p_val_e; + +/* Max valid value for PGS. */ +#define GPT_PGS_MAX (2U) + +/* Max valid value for PPS. */ +#define GPT_PPS_MAX (6U) + +/******************************************************************************/ +/* L0 address attribute macros */ +/******************************************************************************/ + +/* + * If S is greater than or equal to T then there is a single L0 region covering + * the entire protected space so there is no L0 index, so the width (and the + * derivative mask value) are both zero. If we don't specifically handle this + * special case we'll get a negative width value which does not make sense and + * could cause a lot of problems. + */ +#define GPT_L0_IDX_WIDTH(_t) (((_t) > GPT_S_VAL) ? \ + ((_t) - GPT_S_VAL) : (0U)) + +/* Bit shift for the L0 index field in a PA. */ +#define GPT_L0_IDX_SHIFT (GPT_S_VAL) + +/* Mask for the L0 index field, must be shifted. */ +#define GPT_L0_IDX_MASK(_t) (0xFFFFFFFFFFFFFFFFUL >> \ + (64U - (GPT_L0_IDX_WIDTH(_t)))) + +/* Total number of L0 regions. */ +#define GPT_L0_REGION_COUNT(_t) ((GPT_L0_IDX_MASK(_t)) + 1U) + +/* Total size of each GPT L0 region in bytes. */ +#define GPT_L0_REGION_SIZE (1UL << (GPT_L0_IDX_SHIFT)) + +/* Total size in bytes of the whole L0 table. */ +#define GPT_L0_TABLE_SIZE(_t) ((GPT_L0_REGION_COUNT(_t)) << 3U) + +/******************************************************************************/ +/* L1 address attribute macros */ +/******************************************************************************/ + +/* Width of the L1 index field. */ +#define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - ((_p) + 3U)) + +/* Bit shift for the L1 index field. */ +#define GPT_L1_IDX_SHIFT(_p) ((_p) + 4U) + +/* Mask for the L1 index field, must be shifted. */ +#define GPT_L1_IDX_MASK(_p) (0xFFFFFFFFFFFFFFFFUL >> \ + (64U - (GPT_L1_IDX_WIDTH(_p)))) + +/* Bit shift for the index of the L1 GPI in a PA. */ +#define GPT_L1_GPI_IDX_SHIFT(_p) (_p) + +/* Mask for the index of the L1 GPI in a PA. */ +#define GPT_L1_GPI_IDX_MASK (0xF) + +/* Total number of entries in each L1 table. */ +#define GPT_L1_ENTRY_COUNT(_p) ((GPT_L1_IDX_MASK(_p)) + 1U) + +/* Total size in bytes of each L1 table. */ +#define GPT_L1_TABLE_SIZE(_p) ((GPT_L1_ENTRY_COUNT(_p)) << 3U) + +/******************************************************************************/ +/* General helper macros */ +/******************************************************************************/ + +/* Protected space actual size in bytes. */ +#define GPT_PPS_ACTUAL_SIZE(_t) (1UL << (_t)) + +/* Granule actual size in bytes. */ +#define GPT_PGS_ACTUAL_SIZE(_p) (1UL << (_p)) + +/* L0 GPT region size in bytes. */ +#define GPT_L0GPTSZ_ACTUAL_SIZE (1UL << GPT_S_VAL) + +/* Get the index of the L0 entry from a physical address. */ +#define GPT_L0_IDX(_pa) ((_pa) >> GPT_L0_IDX_SHIFT) + +/* + * This definition is used to determine if a physical address lies on an L0 + * region boundary. + */ +#define GPT_IS_L0_ALIGNED(_pa) (((_pa) & (GPT_L0_REGION_SIZE - U(1))) == U(0)) + +/* Get the type field from an L0 descriptor. */ +#define GPT_L0_TYPE(_desc) (((_desc) >> GPT_L0_TYPE_SHIFT) & \ + GPT_L0_TYPE_MASK) + +/* Create an L0 block descriptor. */ +#define GPT_L0_BLK_DESC(_gpi) (GPT_L0_TYPE_BLK_DESC | \ + (((_gpi) & GPT_L0_BLK_DESC_GPI_MASK) << \ + GPT_L0_BLK_DESC_GPI_SHIFT)) + +/* Create an L0 table descriptor with an L1 table address. */ +#define GPT_L0_TBL_DESC(_pa) (GPT_L0_TYPE_TBL_DESC | ((uint64_t)(_pa) & \ + (GPT_L0_TBL_DESC_L1ADDR_MASK << \ + GPT_L0_TBL_DESC_L1ADDR_SHIFT))) + +/* Get the GPI from an L0 block descriptor. */ +#define GPT_L0_BLKD_GPI(_desc) (((_desc) >> GPT_L0_BLK_DESC_GPI_SHIFT) & \ + GPT_L0_BLK_DESC_GPI_MASK) + +/* Get the L1 address from an L0 table descriptor. */ +#define GPT_L0_TBLD_ADDR(_desc) ((uint64_t *)(((_desc) & \ + (GPT_L0_TBL_DESC_L1ADDR_MASK << \ + GPT_L0_TBL_DESC_L1ADDR_SHIFT)))) + +/* Get the index into the L1 table from a physical address. */ +#define GPT_L1_IDX(_p, _pa) (((_pa) >> GPT_L1_IDX_SHIFT(_p)) & \ + GPT_L1_IDX_MASK(_p)) + +/* Get the index of the GPI within an L1 table entry from a physical address. */ +#define GPT_L1_GPI_IDX(_p, _pa) (((_pa) >> GPT_L1_GPI_IDX_SHIFT(_p)) & \ + GPT_L1_GPI_IDX_MASK) + +/* Determine if an address is granule-aligned. */ +#define GPT_IS_L1_ALIGNED(_p, _pa) (((_pa) & (GPT_PGS_ACTUAL_SIZE(_p) - U(1))) \ + == U(0)) + +#endif /* GPT_RME_PRIVATE_H */ diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index ef372068a..2871b1bf0 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -18,12 +18,16 @@ #include #include #include -#include +#if ENABLE_RME +#include +#endif /* ENABLE_RME */ #ifdef SPD_opteed #include #endif #include +#if ENABLE_RME #include +#endif /* ENABLE_RME */ #include #include @@ -130,6 +134,7 @@ void bl2_platform_setup(void) } #if ENABLE_RME + static void arm_bl2_plat_gpt_setup(void) { /* @@ -137,32 +142,38 @@ static void arm_bl2_plat_gpt_setup(void) * the layout, so the array cannot be constant. */ pas_region_t pas_regions[] = { - ARM_PAS_GPI_ANY, ARM_PAS_KERNEL, - ARM_PAS_TZC, + ARM_PAS_SECURE, ARM_PAS_REALM, ARM_PAS_EL3_DRAM, ARM_PAS_GPTS }; - gpt_init_params_t gpt_params = { - PLATFORM_PGS, - PLATFORM_PPS, - PLATFORM_L0GPTSZ, - pas_regions, - (unsigned int)(sizeof(pas_regions)/sizeof(pas_region_t)), - ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, - ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE - }; + /* Initialize entire protected space to GPT_GPI_ANY. */ + if (gpt_init_l0_tables(GPCCR_PPS_4GB, ARM_L0_GPT_ADDR_BASE, + ARM_L0_GPT_SIZE) < 0) { + ERROR("gpt_init_l0_tables() failed!\n"); + panic(); + } - /* Initialise the global granule tables */ - INFO("Enabling Granule Protection Checks\n"); - if (gpt_init(&gpt_params) < 0) { + /* Carve out defined PAS ranges. */ + if (gpt_init_pas_l1_tables(GPCCR_PGS_4K, + ARM_L1_GPT_ADDR_BASE, + ARM_L1_GPT_SIZE, + pas_regions, + (unsigned int)(sizeof(pas_regions) / + sizeof(pas_region_t))) < 0) { + ERROR("gpt_init_pas_l1_tables() failed!\n"); panic(); } - gpt_enable(); + INFO("Enabling Granule Protection Checks\n"); + if (gpt_enable() < 0) { + ERROR("gpt_enable() failed!\n"); + panic(); + } } + #endif /* ENABLE_RME */ /******************************************************************************* @@ -201,9 +212,6 @@ void arm_bl2_plat_arch_setup(void) #if ENABLE_RME /* Initialise the secure environment */ plat_arm_security_setup(); - - /* Initialise and enable Granule Protection */ - arm_bl2_plat_gpt_setup(); #endif setup_page_tables(bl_regions, plat_arm_get_mmap()); @@ -212,6 +220,9 @@ void arm_bl2_plat_arch_setup(void) /* BL2 runs in EL3 when RME enabled. */ assert(get_armv9_2_feat_rme_support() != 0U); enable_mmu_el3(0); + + /* Initialise and enable granule protection after MMU. */ + arm_bl2_plat_gpt_setup(); #else enable_mmu_el1(0); #endif diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index d131bb95b..6472590f3 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -13,10 +13,11 @@ #include #include #include -#include +#if ENABLE_RME +#include +#endif #include #include -#include #include #include #include @@ -235,28 +236,6 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi */ bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; #endif - -#if ENABLE_RME - /* - * Initialise Granule Protection library and enable GPC - * for the primary processor. The tables were initialised - * in BL2, so there is no need to provide any PAS here. - */ - gpt_init_params_t gpt_params = { - PLATFORM_PGS, - PLATFORM_PPS, - PLATFORM_L0GPTSZ, - NULL, - 0U, - ARM_L0_GPT_ADDR_BASE, ARM_L0_GPT_SIZE, - ARM_L1_GPT_ADDR_BASE, ARM_L1_GPT_SIZE - }; - - /* Initialise the global granule tables. */ - if (gpt_init(&gpt_params) < 0) { - panic(); - } -#endif /* ENABLE_RME */ } void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, @@ -430,6 +409,19 @@ void __init arm_bl31_plat_arch_setup(void) enable_mmu_el3(0); +#if ENABLE_RME + /* + * Initialise Granule Protection library and enable GPC for the primary + * processor. The tables have already been initialized by a previous BL + * stage, so there is no need to provide any PAS here. This function + * sets up pointers to those tables. + */ + if (gpt_runtime_init() < 0) { + ERROR("gpt_runtime_init() failed!\n"); + panic(); + } +#endif /* ENABLE_RME */ + arm_setup_romlib(); } diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c index 26a5b8464..dacd15087 100644 --- a/services/std_svc/rmmd/rmmd_main.c +++ b/services/std_svc/rmmd/rmmd_main.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include @@ -296,12 +296,18 @@ static int gtsi_transition_granule(uint64_t pa, { int ret; - ret = gpt_transition_pas(pa, src_sec_state, target_pas); + ret = gpt_transition_pas(pa, PAGE_SIZE_4KB, src_sec_state, target_pas); /* Convert TF-A error codes into GTSI error codes */ if (ret == -EINVAL) { + ERROR("[GTSI] Transition failed: invalid %s\n", "address"); + ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa, + src_sec_state, target_pas); ret = GRAN_TRANS_RET_BAD_ADDR; } else if (ret == -EPERM) { + ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS"); + ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa, + src_sec_state, target_pas); ret = GRAN_TRANS_RET_BAD_PAS; } @@ -328,12 +334,10 @@ uint64_t rmmd_gtsi_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, switch (smc_fid) { case SMC_ASC_MARK_REALM: SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM, - GPI_REALM)); - break; + GPT_GPI_REALM)); case SMC_ASC_MARK_NONSECURE: SMC_RET1(handle, gtsi_transition_granule(x1, SMC_FROM_REALM, - GPI_NS)); - break; + GPT_GPI_NS)); default: WARN("RMM: Unsupported GTF call 0x%08x\n", smc_fid); SMC_RET1(handle, SMC_UNK); -- cgit v1.2.3 From bf39318d93c270ff72bda4b46e4771aba7aea313 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 16 Sep 2020 16:41:55 +0200 Subject: fix(stm32mp1_clk): set other clocks as always on AXI, MPU and MCU clocks are always on, put them in the list in the function clock_is_always_on(). Change-Id: I969a442274d2da6c59636f3293de1c31b4c8e3b1 Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp1_clk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 9764a9f2d..a341cdb19 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1091,6 +1091,9 @@ static bool clock_is_always_on(unsigned long id) case PLL3_P: case PLL3_Q: case PLL3_R: + case CK_AXI: + case CK_MPU: + case CK_MCU: return true; default: return false; -- cgit v1.2.3 From ba57711c38c965e0c33bf9e5c4f6e3adfc59b4d4 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 22 Oct 2020 15:37:22 +0200 Subject: refactor(stm32mp_clk): keep RCC node offset To avoid parsing device tree file too often, keep the RCC node offset value in a variable in fdt_get_rcc_node(). Change-Id: Ibb23ff92247d57c65a23517b8f3473f639794d2a Signed-off-by: Yann Gautier --- drivers/st/clk/stm32mp_clkfunc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 2101171a3..d57f120b9 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -163,7 +163,13 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, */ static int fdt_get_rcc_node(void *fdt) { - return fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); + static int node; + + if (node <= 0) { + node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT); + } + + return node; } /* -- cgit v1.2.3 From b8fe48b6f2b07fce49363cb3c0f8dac9e286439b Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Thu, 19 Dec 2019 10:03:23 +0100 Subject: fix(stm32mp1_clk): fix MCU/AXI parent clock Correct MCU clock parent selector: MCU subsystem clock is derived from clock PLL3_P, not PLL3. Correct AXI clock parent selector: AXI subsystem clock is derived from clock PLL2_P, not PLL2. This change also renames MCU clock and AXI clock resources to prevent confusion. Change-Id: If55618d180e7dce8e4f0977b0e586a6fa8ef28d1 Signed-off-by: Etienne Carriere --- drivers/st/clk/stm32mp1_clk.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 80b6408e4..d1fc57827 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -467,12 +467,12 @@ static const uint8_t fmc_parents[] = { _ACLK, _PLL3_R, _PLL4_P, _CK_PER }; -static const uint8_t ass_parents[] = { - _HSI, _HSE, _PLL2 +static const uint8_t axiss_parents[] = { + _HSI, _HSE, _PLL2_P }; -static const uint8_t mss_parents[] = { - _HSI, _HSE, _CSI, _PLL3 +static const uint8_t mcuss_parents[] = { + _HSI, _HSE, _CSI, _PLL3_P }; static const uint8_t usbphy_parents[] = { @@ -514,8 +514,8 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { _CLK_PARENT_SEL(SDMMC3, RCC_SDMMC3CKSELR, sdmmc3_parents), _CLK_PARENT_SEL(QSPI, RCC_QSPICKSELR, qspi_parents), _CLK_PARENT_SEL(FMC, RCC_FMCCKSELR, fmc_parents), - _CLK_PARENT_SEL(AXIS, RCC_ASSCKSELR, ass_parents), - _CLK_PARENT_SEL(MCUS, RCC_MSSCKSELR, mss_parents), + _CLK_PARENT_SEL(AXIS, RCC_ASSCKSELR, axiss_parents), + _CLK_PARENT_SEL(MCUS, RCC_MSSCKSELR, mcuss_parents), _CLK_PARENT_SEL(USBPHY, RCC_USBCKSELR, usbphy_parents), _CLK_PARENT_SEL(USBO, RCC_USBCKSELR, usbo_parents), }; -- cgit v1.2.3 From 602ae2f23c2bc9d79a9ab2b7c5dde1932fffc984 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Fri, 28 Feb 2020 09:09:06 +0100 Subject: fix(stm32mp1_clk): fix MPU clock rate MPUDIV dividers are stored in a constant array, under bit shifts form. They must be used in this way by the clock driver. Change-Id: If758f7a4048eff956067a10a42ab0983a20a000d Signed-off-by: Gabriel Fernandez Signed-off-by: Nicolas Le Bayon --- drivers/st/clk/stm32mp1_clk.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index d1fc57827..9764a9f2d 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -850,9 +850,7 @@ static unsigned long get_clock_rate(int p) reg = mmio_read_32(rcc_base + RCC_MPCKDIVR); clkdiv = reg & RCC_MPUDIV_MASK; - if (clkdiv != 0U) { - clock /= stm32mp1_mpu_div[clkdiv]; - } + clock >>= stm32mp1_mpu_div[clkdiv]; break; default: break; -- cgit v1.2.3 From ea97bbf6a001b270fd0a25b4b0d0c382e277f3f8 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 29 Sep 2021 11:31:09 +0200 Subject: feat(plat/st): create new helper for DT access dt_match_instance_by_compatible() gives the DT node offset in DT that matches both compatible and the peripheral instance address. Change-Id: Ia85f4f4aa8fe8efd4df310d765e7586e67aa34c2 Signed-off-by: Yann Gautier --- plat/st/common/include/stm32mp_dt.h | 1 + plat/st/common/stm32mp_dt.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index 299c0b1cb..f7201c0d9 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -34,6 +34,7 @@ int dt_set_stdout_pinctrl(void); void dt_fill_device_info(struct dt_node_info *info, int node); int dt_get_node(struct dt_node_info *info, int offset, const char *compat); int dt_get_stdout_uart_info(struct dt_node_info *info); +int dt_match_instance_by_compatible(const char *compatible, uintptr_t address); uint32_t dt_get_ddr_size(void); uint32_t dt_get_pwr_vdd_voltage(void); const char *dt_get_board_model(void); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index 0b3564692..4dc990896 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -203,6 +203,33 @@ int dt_get_stdout_uart_info(struct dt_node_info *info) return node; } +/******************************************************************************* + * This function returns the node offset matching compatible string in the DT, + * and also matching the reg property with the given address. + * Returns value on success, and error value on failure. + ******************************************************************************/ +int dt_match_instance_by_compatible(const char *compatible, uintptr_t address) +{ + int node; + + fdt_for_each_compatible_node(fdt, node, compatible) { + const fdt32_t *cuint; + + assert(fdt_get_node_parent_address_cells(node) == 1); + + cuint = fdt_getprop(fdt, node, "reg", NULL); + if (cuint == NULL) { + continue; + } + + if ((uintptr_t)fdt32_to_cpu(*cuint) == address) { + return node; + } + } + + return -FDT_ERR_NOTFOUND; +} + /******************************************************************************* * This function gets DDR size information from the DT. * Returns value in bytes on success, and 0 on failure. -- cgit v1.2.3 From bff9e3ccc2a1add06a1b0e541bd8ee1cb9a5d071 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 4 Nov 2019 14:27:23 +0100 Subject: refactor(stm32_sdmmc2): use DT helpers Use dt_match_instance_by_compatible() and dt_fill_device_info() functions to simplify SDMMC driver code. Change-Id: Id16aa849ac79a9d3c2dc72c947fe189743856292 Signed-off-by: Yann Gautier --- drivers/st/mmc/stm32_sdmmc2.c | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index cff3a344f..d3adeab13 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -628,6 +628,7 @@ static int stm32_sdmmc2_dt_get_config(void) int sdmmc_node; void *fdt = NULL; const fdt32_t *cuint; + struct dt_node_info dt_info; if (fdt_get_address(&fdt) == 0) { return -FDT_ERR_NOTFOUND; @@ -637,27 +638,14 @@ static int stm32_sdmmc2_dt_get_config(void) return -FDT_ERR_NOTFOUND; } - sdmmc_node = fdt_node_offset_by_compatible(fdt, -1, DT_SDMMC2_COMPAT); - - while (sdmmc_node != -FDT_ERR_NOTFOUND) { - cuint = fdt_getprop(fdt, sdmmc_node, "reg", NULL); - if (cuint == NULL) { - continue; - } - - if (fdt32_to_cpu(*cuint) == sdmmc2_params.reg_base) { - break; - } - - sdmmc_node = fdt_node_offset_by_compatible(fdt, sdmmc_node, - DT_SDMMC2_COMPAT); - } - + sdmmc_node = dt_match_instance_by_compatible(DT_SDMMC2_COMPAT, + sdmmc2_params.reg_base); if (sdmmc_node == -FDT_ERR_NOTFOUND) { return -FDT_ERR_NOTFOUND; } - if (fdt_get_status(sdmmc_node) == DT_DISABLED) { + dt_fill_device_info(&dt_info, sdmmc_node); + if (dt_info.status == DT_DISABLED) { return -FDT_ERR_NOTFOUND; } @@ -665,21 +653,8 @@ static int stm32_sdmmc2_dt_get_config(void) return -FDT_ERR_BADVALUE; } - cuint = fdt_getprop(fdt, sdmmc_node, "clocks", NULL); - if (cuint == NULL) { - return -FDT_ERR_NOTFOUND; - } - - cuint++; - sdmmc2_params.clock_id = fdt32_to_cpu(*cuint); - - cuint = fdt_getprop(fdt, sdmmc_node, "resets", NULL); - if (cuint == NULL) { - return -FDT_ERR_NOTFOUND; - } - - cuint++; - sdmmc2_params.reset_id = fdt32_to_cpu(*cuint); + sdmmc2_params.clock_id = dt_info.clock; + sdmmc2_params.reset_id = dt_info.reset; if ((fdt_getprop(fdt, sdmmc_node, "st,use-ckin", NULL)) != NULL) { sdmmc2_params.pin_ckin = SDMMC_CLKCR_SELCLKRX_0; -- cgit v1.2.3 From 5b111c74795ea5e9c8a12d0e6b18d77e431311ed Mon Sep 17 00:00:00 2001 From: HE Shushan Date: Mon, 12 Jul 2021 23:04:10 +0200 Subject: fix(stm32mp1_clk): keep RTC clock always on On battery powered systems the RTC keeps the date/time across system reboot. The RTC clock should not be disabled otherwise the date/time counter gets stopped. Tag RTC clock as always on. Signed-off-by: HE Shushan Signed-off-by: Antonio Borneo Change-Id: I6455c3c740d2e5add28255eb84f8ebaf2870d9d8 --- drivers/st/clk/stm32mp1_clk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index a341cdb19..3ebc376cd 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -1094,6 +1094,7 @@ static bool clock_is_always_on(unsigned long id) case CK_AXI: case CK_MPU: case CK_MCU: + case RTC: return true; default: return false; -- cgit v1.2.3 From 4bafa3dad081f9f0b93579742f7fd08541e5d45c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 14 Sep 2021 18:12:42 +0200 Subject: refactor(stpmic1): use BIT and GENMASK helpers Use BIT and GENMASK macros to ease stpmic1.h reading. Change-Id: I808a62818d4188bb2f3686ab37518d369b6c41cb Signed-off-by: Yann Gautier --- include/drivers/st/stpmic1.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/drivers/st/stpmic1.h b/include/drivers/st/stpmic1.h index f7e293b18..dc096cd1a 100644 --- a/include/drivers/st/stpmic1.h +++ b/include/drivers/st/stpmic1.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -86,15 +86,15 @@ #define ITSOURCE4_REG 0xB3U /* Registers masks */ -#define LDO_VOLTAGE_MASK 0x7CU -#define BUCK_VOLTAGE_MASK 0xFCU +#define LDO_VOLTAGE_MASK GENMASK(6, 2) +#define BUCK_VOLTAGE_MASK GENMASK(7, 2) #define LDO_BUCK_VOLTAGE_SHIFT 2 -#define LDO_BUCK_ENABLE_MASK 0x01U -#define LDO_BUCK_HPLP_ENABLE_MASK 0x02U +#define LDO_BUCK_ENABLE_MASK BIT(0) +#define LDO_BUCK_HPLP_ENABLE_MASK BIT(1) #define LDO_BUCK_HPLP_SHIFT 1 -#define LDO_BUCK_RANK_MASK 0x01U -#define LDO_BUCK_RESET_MASK 0x01U -#define LDO_BUCK_PULL_DOWN_MASK 0x03U +#define LDO_BUCK_RANK_MASK BIT(0) +#define LDO_BUCK_RESET_MASK BIT(0) +#define LDO_BUCK_PULL_DOWN_MASK GENMASK(1, 0) /* Pull down register */ #define BUCK1_PULL_DOWN_SHIFT 0 @@ -135,12 +135,12 @@ /* Main PMIC VINLOW Control Register (VIN_CONTROL_REGC DMSC) */ #define SWIN_DETECTOR_ENABLED BIT(7) #define SWOUT_DETECTOR_ENABLED BIT(6) -#define VINLOW_HYST_MASK 0x3 +#define VINLOW_HYST_MASK GENMASK(1, 0) #define VINLOW_HYST_SHIFT 4 -#define VINLOW_THRESHOLD_MASK 0x7 +#define VINLOW_THRESHOLD_MASK GENMASK(2, 0) #define VINLOW_THRESHOLD_SHIFT 1 -#define VINLOW_ENABLED 0x01 -#define VINLOW_CTRL_REG_MASK 0xFF +#define VINLOW_ENABLED BIT(0) +#define VINLOW_CTRL_REG_MASK GENMASK(7, 0) /* USB Control Register */ #define BOOST_OVP_DISABLED BIT(7) -- cgit v1.2.3 From ed6a85234653c5ee2520389b769ff47e321df8a4 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 23 Mar 2020 17:44:30 +0100 Subject: fix(stpmic1): update error cases return Use errno values, or the return of called functions, instead of -1. Correct some MISRA issues, like braces. Change-Id: If7b53de5cbfb4d2c9979bce0e594dd92bf07a77a Signed-off-by: Yann Gautier --- drivers/st/pmic/stpmic1.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c index 999963054..d4e5471da 100644 --- a/drivers/st/pmic/stpmic1.c +++ b/drivers/st/pmic/stpmic1.c @@ -1,9 +1,10 @@ /* - * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2016-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -653,6 +654,7 @@ int stpmic1_regulator_voltage_get(const char *name) const struct regul_struct *regul = get_regulator_data(name); uint8_t value; uint8_t mask; + int status; /* Voltage can be set for buck or ldo (except ldo4) regulators */ if (strncmp(name, "buck", 4) == 0) { @@ -664,13 +666,16 @@ int stpmic1_regulator_voltage_get(const char *name) return 0; } - if (stpmic1_register_read(regul->control_reg, &value)) - return -1; + status = stpmic1_register_read(regul->control_reg, &value); + if (status < 0) { + return status; + } value = (value & mask) >> LDO_BUCK_VOLTAGE_SHIFT; - if (value > regul->voltage_table_size) - return -1; + if (value > regul->voltage_table_size) { + return -ERANGE; + } return (int)regul->voltage_table[value]; } @@ -706,7 +711,7 @@ int stpmic1_register_write(uint8_t register_id, uint8_t value) } if (readval != value) { - return -1; + return -EIO; } } #endif @@ -751,12 +756,12 @@ void stpmic1_dump_regulators(void) int stpmic1_get_version(unsigned long *version) { - int rc; uint8_t read_val; + int status; - rc = stpmic1_register_read(VERSION_STATUS_REG, &read_val); - if (rc) { - return -1; + status = stpmic1_register_read(VERSION_STATUS_REG, &read_val); + if (status < 0) { + return status; } *version = (unsigned long)read_val; -- cgit v1.2.3 From 0161991184e5feacacc679bdb9c92681b85235eb Mon Sep 17 00:00:00 2001 From: Pascal Paillet Date: Wed, 10 Mar 2021 14:37:03 +0100 Subject: fix(stpmic1): fix power switches activation Add enable bit mask description because power switches are not all enabled by bit 0. Signed-off-by: Pascal Paillet Change-Id: If7c9ae7d800adee8e25416ca35db1be20452741f --- drivers/st/pmic/stpmic1.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/st/pmic/stpmic1.c b/drivers/st/pmic/stpmic1.c index d4e5471da..0a35df372 100644 --- a/drivers/st/pmic/stpmic1.c +++ b/drivers/st/pmic/stpmic1.c @@ -17,6 +17,7 @@ struct regul_struct { const uint16_t *voltage_table; uint8_t voltage_table_size; uint8_t control_reg; + uint8_t enable_mask; uint8_t low_power_reg; uint8_t pull_down_reg; uint8_t pull_down; @@ -427,6 +428,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = buck1_voltage_table, .voltage_table_size = ARRAY_SIZE(buck1_voltage_table), .control_reg = BUCK1_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = BUCK1_PWRCTRL_REG, .pull_down_reg = BUCK_PULL_DOWN_REG, .pull_down = BUCK1_PULL_DOWN_SHIFT, @@ -438,6 +440,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = buck2_voltage_table, .voltage_table_size = ARRAY_SIZE(buck2_voltage_table), .control_reg = BUCK2_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = BUCK2_PWRCTRL_REG, .pull_down_reg = BUCK_PULL_DOWN_REG, .pull_down = BUCK2_PULL_DOWN_SHIFT, @@ -449,6 +452,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = buck3_voltage_table, .voltage_table_size = ARRAY_SIZE(buck3_voltage_table), .control_reg = BUCK3_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = BUCK3_PWRCTRL_REG, .pull_down_reg = BUCK_PULL_DOWN_REG, .pull_down = BUCK3_PULL_DOWN_SHIFT, @@ -460,6 +464,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = buck4_voltage_table, .voltage_table_size = ARRAY_SIZE(buck4_voltage_table), .control_reg = BUCK4_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = BUCK4_PWRCTRL_REG, .pull_down_reg = BUCK_PULL_DOWN_REG, .pull_down = BUCK4_PULL_DOWN_SHIFT, @@ -471,6 +476,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo1_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table), .control_reg = LDO1_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO1_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO1_MASK_RESET, @@ -480,6 +486,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo2_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table), .control_reg = LDO2_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO2_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO2_MASK_RESET, @@ -489,6 +496,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo3_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table), .control_reg = LDO3_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO3_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO3_MASK_RESET, @@ -498,6 +506,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo4_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table), .control_reg = LDO4_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO4_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO4_MASK_RESET, @@ -507,6 +516,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo5_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table), .control_reg = LDO5_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO5_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO5_MASK_RESET, @@ -516,6 +526,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = ldo6_voltage_table, .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table), .control_reg = LDO6_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = LDO6_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = LDO6_MASK_RESET, @@ -525,6 +536,7 @@ static const struct regul_struct regulators_table[] = { .voltage_table = vref_ddr_voltage_table, .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table), .control_reg = VREF_DDR_CONTROL_REG, + .enable_mask = LDO_BUCK_ENABLE_MASK, .low_power_reg = VREF_DDR_PWRCTRL_REG, .mask_reset_reg = MASK_RESET_LDO_REG, .mask_reset = VREF_DDR_MASK_RESET, @@ -582,14 +594,16 @@ int stpmic1_regulator_enable(const char *name) { const struct regul_struct *regul = get_regulator_data(name); - return stpmic1_register_update(regul->control_reg, BIT(0), BIT(0)); + return stpmic1_register_update(regul->control_reg, regul->enable_mask, + regul->enable_mask); } int stpmic1_regulator_disable(const char *name) { const struct regul_struct *regul = get_regulator_data(name); - return stpmic1_register_update(regul->control_reg, 0, BIT(0)); + return stpmic1_register_update(regul->control_reg, 0, + regul->enable_mask); } uint8_t stpmic1_is_regulator_enabled(const char *name) @@ -601,7 +615,7 @@ uint8_t stpmic1_is_regulator_enabled(const char *name) panic(); } - return (val & 0x1U); + return (val & regul->enable_mask); } int stpmic1_regulator_voltage_set(const char *name, uint16_t millivolts) -- cgit v1.2.3 From 8ce89187459ec77dd9ffdffba3a2b77838d51b6d Mon Sep 17 00:00:00 2001 From: Nicolas Le Bayon Date: Mon, 18 Nov 2019 17:12:27 +0100 Subject: fix(plat/st): only check header major when booting An STM32 image with the awaited header major version shouldn't be forbid to boot. If the minor differs, then it means only non-mandatory options have been added in the reserved fields, and the header remains backward compatible. Change-Id: Iff16b67f95c728e2f1d128bd1760a4be497c5ca3 Signed-off-by: Yann Gautier --- plat/st/common/stm32mp_common.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plat/st/common/stm32mp_common.c b/plat/st/common/stm32mp_common.c index 17ac145ab..91204089b 100644 --- a/plat/st/common/stm32mp_common.c +++ b/plat/st/common/stm32mp_common.c @@ -17,6 +17,8 @@ #include #include +#define HEADER_VERSION_MAJOR_MASK GENMASK(23, 16) + uintptr_t plat_get_ns_image_entrypoint(void) { return BL33_BASE; @@ -93,7 +95,8 @@ int stm32mp_check_header(boot_api_image_header_t *header, uintptr_t buffer) return -EINVAL; } - if (header->header_version != BOOT_API_HEADER_VERSION) { + if ((header->header_version & HEADER_VERSION_MAJOR_MASK) != + (BOOT_API_HEADER_VERSION & HEADER_VERSION_MAJOR_MASK)) { ERROR("Header version\n"); return -EINVAL; } -- cgit v1.2.3 From 1ff7e46b092b74891bc2dc7263e4dfae947b2223 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Wed, 6 Oct 2021 14:47:27 +0530 Subject: fix(include/drivers/flexspi): fix warm boot wait time for MT35XU512A Now lx2 which use MT35XU512A supports warm boot, fix the macro define caused by the commit: feat(driver/nxp/xspi): add MT35XU02G flash info Signed-off-by: Pankaj Gupta Change-Id: I83eb8cb9a30ac7c7efd5a010acbd03eddebed52b --- include/drivers/nxp/flexspi/flash_info.h | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/include/drivers/nxp/flexspi/flash_info.h b/include/drivers/nxp/flexspi/flash_info.h index 94c9f027c..d0ffc86b4 100644 --- a/include/drivers/nxp/flexspi/flash_info.h +++ b/include/drivers/nxp/flexspi/flash_info.h @@ -12,6 +12,7 @@ #define SZ_16M_BYTES 0x1000000U +/* Start of "if defined(CONFIG_MT25QU512A)" */ #if defined(CONFIG_MT25QU512A) #define F_SECTOR_64K 0x10000U #define F_PAGE_256 0x100U @@ -22,6 +23,9 @@ #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif +/* End of "if defined(CONFIG_MT25QU512A)" */ + +/* Start of "if defined(CONFIG_MX25U25645G)" */ #elif defined(CONFIG_MX25U25645G) #define F_SECTOR_64K 0x10000U #define F_PAGE_256 0x100U @@ -32,6 +36,9 @@ #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif +/* End of "if defined(CONFIG_MX25U25645G)" */ + +/* Start of "if defined(CONFIG_MX25U51245G)" */ #elif defined(CONFIG_MX25U51245G) #define F_SECTOR_64K 0x10000U #define F_PAGE_256 0x100U @@ -42,6 +49,9 @@ #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif +/* End of "if defined(CONFIG_MX25U51245G)" */ + +/* Start of "if defined(CONFIG_MT35XU512A)" */ #elif defined(CONFIG_MT35XU512A) #define F_SECTOR_128K 0x20000U #define F_SECTOR_32K 0x8000U @@ -52,7 +62,18 @@ #ifdef CONFIG_FSPI_4K_ERASE #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif +/* If Warm boot is enabled for the platform, + * count of arm instruction N-OP(s) to mark + * the completion of write operation to flash; + * varies from one flash to other. + */ +#ifdef NXP_WARM_BOOT +#define FLASH_WR_COMP_WAIT_BY_NOP_COUNT 0x20000 +#endif + +/* End of "if defined(CONFIG_MT35XU512A)" */ +/* Start of #elif defined(CONFIG_MT35XU02G) */ #elif defined(CONFIG_MT35XU02G) #define F_SECTOR_128K 0x20000U #define F_PAGE_256 0x100U @@ -63,9 +84,6 @@ #define F_SECTOR_ERASE_SZ F_SECTOR_4K #endif -#ifdef NXP_WARM_BOOT -#define FLASH_WR_COMP_WAIT_BY_NOP_COUNT 0x20000 -#endif +#endif /* End of #elif defined(CONFIG_MT35XU02G) */ -#endif #endif /* FLASH_INFO_H */ -- cgit v1.2.3 From 322e60a6c7ad95a874e5eaf2de5db4f6e1912ba9 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 6 Oct 2021 17:34:12 +0200 Subject: fix(errata_report): correct typo Change wrong __arch64__ to __aarch64__. Change-Id: I750fdb16958e0eadf8aebe24bec0e14488fa4787 Signed-off-by: Yann Gautier --- lib/cpus/errata_report.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/cpus/errata_report.c b/lib/cpus/errata_report.c index 5d1e3c5cc..93b27444f 100644 --- a/lib/cpus/errata_report.c +++ b/lib/cpus/errata_report.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,7 @@ # define BL_STRING "BL1" #elif defined(__aarch64__) && defined(IMAGE_BL31) # define BL_STRING "BL31" -#elif !defined(__arch64__) && defined(IMAGE_BL32) +#elif !defined(__aarch64__) && defined(IMAGE_BL32) # define BL_STRING "BL32" #elif defined(IMAGE_BL2) && BL2_AT_EL3 # define BL_STRING "BL2" -- cgit v1.2.3 From 5f24ce968ed2fa7749379b8a56aaeea333921e88 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 6 Oct 2021 10:59:52 +0100 Subject: refactor(Makefile): move NEED_ before their use In later patch tbbr_tools.mk requires NEED_BL2 definition which is defined after inclusion of this mk file. Move NEED_ definitions earlier to their use Signed-off-by: Manish Pandey Change-Id: Ieff999b255690755779d0cd35d5aba2d3794873c --- Makefile | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 59d14ba02..ef815977e 100644 --- a/Makefile +++ b/Makefile @@ -776,10 +776,16 @@ endif # Process platform overrideable behaviour ################################################################################ -# Using BL2 implies that a BL33 image also needs to be supplied for the FIP and -# Certificate generation tools. This flag can be overridden by the platform. +ifdef BL1_SOURCES +NEED_BL1 := yes +endif + ifdef BL2_SOURCES - ifdef EL3_PAYLOAD_BASE + NEED_BL2 := yes + + # Using BL2 implies that a BL33 image also needs to be supplied for the FIP and + # Certificate generation tools. This flag can be overridden by the platform. + ifdef EL3_PAYLOAD_BASE # If booting an EL3 payload there is no need for a BL33 image # in the FIP file. NEED_BL33 := no @@ -794,6 +800,10 @@ ifdef BL2_SOURCES endif endif +ifdef BL2U_SOURCES +NEED_BL2U := yes +endif + # If SCP_BL2 is given, we always want FIP to include it. ifdef SCP_BL2 NEED_SCP_BL2 := yes @@ -831,6 +841,10 @@ ifneq (${FIP_ALIGN},0) FIP_ARGS += --align ${FIP_ALIGN} endif +ifdef FDT_SOURCES +NEED_FDT := yes +endif + ################################################################################ # Include libraries' Makefile that are used in all BL ################################################################################ @@ -874,30 +888,22 @@ DOCS_PATH ?= docs ################################################################################ # Include BL specific makefiles ################################################################################ -ifdef BL1_SOURCES -NEED_BL1 := yes + +ifeq (${NEED_BL1},yes) include bl1/bl1.mk endif -ifdef BL2_SOURCES -NEED_BL2 := yes +ifeq (${NEED_BL2},yes) include bl2/bl2.mk endif -ifdef BL2U_SOURCES -NEED_BL2U := yes +ifeq (${NEED_BL2U},yes) include bl2u/bl2u.mk endif ifeq (${NEED_BL31},yes) -ifdef BL31_SOURCES include bl31/bl31.mk endif -endif - -ifdef FDT_SOURCES -NEED_FDT := yes -endif ################################################################################ # Build options checks -- cgit v1.2.3 From 08c699e738ff8937f654f1ac23891e89536f10bb Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 1 Oct 2021 14:34:33 +0100 Subject: refactor(tbbr): remove "fvp_r" platform specific check fvp_r is a unique platform which does not have BL2 binary and image loading functionality is performed by BL1 itself. To avoid generating certificate for BL2 there was platform specific check added which looks bit ugly, replacing that check. Signed-off-by: Manish Pandey Change-Id: I11360fa753f847768906c42dce652296245b4a63 --- make_helpers/tbbr/tbbr_tools.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index 293e85487..0a280b4ed 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -11,6 +11,7 @@ # Expected environment: # # BUILD_PLAT: output directory +# NEED_BL2: indicates whether BL2 is needed by the platform # NEED_BL32: indicates whether BL32 is needed by the platform # BL2: image filename (optional). Default is IMG_BIN(2) (see macro IMG_BIN) # SCP_BL2: image filename (optional). Default is IMG_BIN(30) @@ -67,8 +68,8 @@ $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD # Add the BL2 CoT (image cert) +ifeq (${NEED_BL2},yes) ifeq (${BL2_AT_EL3}, 0) -ifneq (${PLAT},fvp_r) $(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert)) endif endif -- cgit v1.2.3 From 4796c6ca89c4d5665f744ecaba3637f7ebb5b29c Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Mon, 4 Oct 2021 13:38:56 +0100 Subject: refactor(fvp_r): tidy up platform port [1] Following changes done: 1. Remove "fvp_r" specific check from bl1.mk 2. Override BL1_SOURCES in fvp_r platform.mk 3. Regroup source files 4. Remove platform specific change from arm_common Signed-off-by: Manish Pandey Change-Id: I74d0b1f317853ab1333744d8da5c59f937789547 --- bl1/bl1.mk | 6 +- plat/arm/board/fvp_r/fvp_r_bl1_setup.c | 2 +- plat/arm/board/fvp_r/platform.mk | 117 +++++++++++++++++++-------------- plat/arm/common/arm_common.mk | 5 -- 4 files changed, 72 insertions(+), 58 deletions(-) diff --git a/bl1/bl1.mk b/bl1/bl1.mk index 8f44151da..9f63fd50f 100644 --- a/bl1/bl1.mk +++ b/bl1/bl1.mk @@ -4,14 +4,12 @@ # SPDX-License-Identifier: BSD-3-Clause # -ifneq (${PLAT},fvp_r) BL1_SOURCES += bl1/${ARCH}/bl1_arch_setup.c \ bl1/${ARCH}/bl1_context_mgmt.c \ bl1/${ARCH}/bl1_entrypoint.S \ bl1/${ARCH}/bl1_exceptions.S \ - bl1/bl1_main.c -endif -BL1_SOURCES += lib/cpus/${ARCH}/cpu_helpers.S \ + bl1/bl1_main.c \ + lib/cpus/${ARCH}/cpu_helpers.S \ lib/cpus/errata_report.c \ lib/el3_runtime/${ARCH}/context_mgmt.c \ plat/common/plat_bl1_common.c \ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c index 5e31d39a2..3f3fd5e9c 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -9,12 +9,12 @@ #include -#include "../../../../lib/xlat_mpu/xlat_mpu.h" #include #include #include #include #include +#include #include "fvp_r_private.h" #include diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk index 39509dd7e..8f5878fd9 100644 --- a/plat/arm/board/fvp_r/platform.mk +++ b/plat/arm/board/fvp_r/platform.mk @@ -11,6 +11,7 @@ ARCH := aarch64 override NEED_BL2 := no override NEED_BL2U := no override NEED_BL31 := no +NEED_BL32 := no override CTX_INCLUDE_AARCH32_REGS := 0 @@ -56,70 +57,90 @@ else $(error "Incorrect CCN driver chosen on FVP_R port") endif -PLAT_INCLUDES := -Iplat/arm/board/fvp_r/include - -PLAT_BL_COMMON_SOURCES := plat/arm/board/fvp_r/fvp_r_common.c - -FVP_R_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S +include plat/arm/board/common/board_common.mk +include plat/arm/common/arm_common.mk -# select a different set of CPU files, depending on whether we compile for -# hardware assisted coherency cores or not -ifeq (${HW_ASSISTED_COHERENCY}, 0) -# Cores used without DSU -# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S -else -# Cores used with DSU only -# FVP_R_CPU_LIBS += lib/cpus/aarch64/fvp_r.S -endif +PLAT_INCLUDES := -Iplat/arm/board/fvp_r/include -BL1_SOURCES += drivers/arm/sp805/sp805.c \ - drivers/delay_timer/delay_timer.c \ - drivers/io/io_semihosting.c \ - lib/semihosting/semihosting.c \ - lib/semihosting/${ARCH}/semihosting_call.S \ - plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \ - plat/arm/board/fvp_r/fvp_r_bl1_setup.c \ +FVP_R_BL_COMMON_SOURCES := plat/arm/board/fvp_r/fvp_r_common.c \ plat/arm/board/fvp_r/fvp_r_context_mgmt.c \ + plat/arm/board/fvp_r/fvp_r_context.S \ + plat/arm/board/fvp_r/fvp_r_debug.S \ plat/arm/board/fvp_r/fvp_r_err.c \ + plat/arm/board/fvp_r/fvp_r_helpers.S \ + plat/arm/board/fvp_r/fvp_r_misc_helpers.S \ + plat/arm/board/fvp_r/fvp_r_pauth_helpers.S + +FVP_R_BL1_SOURCES := plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \ + plat/arm/board/fvp_r/fvp_r_bl1_setup.c \ plat/arm/board/fvp_r/fvp_r_io_storage.c \ plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c \ plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S \ plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S \ - plat/arm/board/fvp_r/fvp_r_bl1_main.c \ - plat/arm/board/fvp_r/fvp_r_context.S \ - plat/arm/board/fvp_r/fvp_r_debug.S \ - plat/arm/board/fvp_r/fvp_r_helpers.S \ - plat/arm/board/fvp_r/fvp_r_misc_helpers.S \ - plat/arm/board/fvp_r/fvp_r_pauth_helpers.S \ - ${FVP_R_CPU_LIBS} \ - ${FVP_R_INTERCONNECT_SOURCES} + plat/arm/board/fvp_r/fvp_r_bl1_main.c + +FVP_R_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S + +FVP_R_DYNC_CFG_SOURCES := common/fdt_wrappers.c \ + common/uuid.c \ + plat/arm/common/arm_dyn_cfg.c \ + plat/arm/common/arm_dyn_cfg_helpers.c + +ifeq (${TRUSTED_BOARD_BOOT},1) +FVP_R_AUTH_SOURCES := drivers/auth/auth_mod.c \ + drivers/auth/crypto_mod.c \ + drivers/auth/img_parser_mod.c \ + lib/fconf/fconf_tbbr_getter.c \ + bl1/tbbr/tbbr_img_desc.c \ + plat/arm/common/arm_bl1_fwu.c \ + plat/common/tbbr/plat_tbbr.c \ + drivers/auth/tbbr/tbbr_cot_bl1_r64.c \ + drivers/auth/tbbr/tbbr_cot_common.c \ + plat/arm/board/common/board_arm_trusted_boot.c \ + plat/arm/board/common/rotpk/arm_dev_rotpk.S \ + plat/arm/board/fvp_r/fvp_r_trusted_boot.c + +FVP_R_BL1_SOURCES += ${MBEDTLS_SOURCES} \ + ${FVP_R_AUTH_SOURCES} +endif ifeq (${USE_SP804_TIMER},1) -BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c +FVP_R_BL_COMMON_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else -BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c +FVP_R_BL_COMMON_SOURCES += drivers/delay_timer/generic_delay_timer.c endif # Enable Activity Monitor Unit extensions by default ENABLE_AMU := 1 ifneq (${ENABLE_STACK_PROTECTOR},0) -PLAT_BL_COMMON_SOURCES += plat/arm/board/fvp_r/fvp_r_stack_protector.c -endif - -NEED_BL32 := no - -ifneq (${BL2_AT_EL3}, 0) - override BL1_SOURCES = +FVP_R_BL_COMMON_SOURCES += plat/arm/board/fvp_r/fvp_r_stack_protector.c endif -include plat/arm/board/common/board_common.mk -include plat/arm/common/arm_common.mk - -ifeq (${TRUSTED_BOARD_BOOT}, 1) -BL1_SOURCES += plat/arm/board/fvp_r/fvp_r_trusted_boot.c - -# FVP being a development platform, enable capability to disable Authentication -# dynamically if TRUSTED_BOARD_BOOT is set. -DYN_DISABLE_AUTH := 1 -endif +override BL1_SOURCES := drivers/arm/sp805/sp805.c \ + drivers/cfi/v2m/v2m_flash.c \ + drivers/delay_timer/delay_timer.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + drivers/io/io_storage.c \ + drivers/io/io_semihosting.c \ + lib/cpus/aarch64/cpu_helpers.S \ + lib/cpus/errata_report.c \ + lib/cpus/aarch64/dsu_helpers.S \ + lib/el3_runtime/aarch64/context.S \ + lib/el3_runtime/aarch64/context_mgmt.c \ + lib/fconf/fconf.c \ + lib/fconf/fconf_dyn_cfg_getter.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + plat/arm/common/arm_bl1_setup.c \ + plat/arm/common/arm_err.c \ + plat/arm/common/arm_io_storage.c \ + plat/arm/common/fconf/arm_fconf_io.c \ + plat/common/plat_bl1_common.c \ + plat/common/aarch64/platform_up_stack.S \ + ${FVP_R_BL1_SOURCES} \ + ${FVP_R_BL_COMMON_SOURCES} \ + ${FVP_R_CPU_LIBS} \ + ${FVP_R_DYNC_CFG_SOURCES} \ + ${FVP_R_INTERCONNECT_SOURCES} diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index dc8c6d01e..3cbae7db4 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -355,13 +355,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) # Include the selected chain of trust sources. ifeq (${COT},tbbr) - ifeq (${PLAT},fvp_r) - BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ - drivers/auth/tbbr/tbbr_cot_bl1_r64.c - else BL1_SOURCES += drivers/auth/tbbr/tbbr_cot_common.c \ drivers/auth/tbbr/tbbr_cot_bl1.c - endif ifneq (${COT_DESC_IN_DTB},0) BL2_SOURCES += lib/fconf/fconf_cot_getter.c else -- cgit v1.2.3 From 28bbbf3bf583e0c85004727e694455dfcabd50a4 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 6 Oct 2021 17:28:09 +0100 Subject: feat(fvp_r): configure system registers to boot rich OS Following system registers are modified before exiting EL2 to allow u-boot/Linux to boot 1. CNTHCTL_EL2.EL1PCTEN -> 1 Allows U-boot to use physical counters at EL1 2. VTCR_EL2.MSA -> 1 Enables VMSA at EL1, which is required by U-Boot and Linux. 3. HCR_EL2.APK = 1 & HCR_EL2.API = 1 Disables PAuth instruction and register traps in EL1 Signed-off-by: Manish Pandey Change-Id: I58f45b6669a9ad1debb80265b243015c054a9bb1 --- include/arch/aarch64/arch.h | 4 ++ include/arch/aarch64/arch_helpers.h | 2 + plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c | 5 ++- plat/arm/board/fvp_r/fvp_r_context_mgmt.c | 59 +++++++++++++++++++-------- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 1b3ae0221..833390272 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -576,6 +576,10 @@ #define CPTR_EL2_TZ_BIT (U(1) << 8) #define CPTR_EL2_RESET_VAL CPTR_EL2_RES1 +/* VTCR_EL2 definitions */ +#define VTCR_RESET_VAL U(0x0) +#define VTCR_EL2_MSA (U(1) << 31) + /* CPSR/SPSR definitions */ #define DAIF_FIQ_BIT (U(1) << 0) #define DAIF_IRQ_BIT (U(1) << 1) diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 72b87c8b9..359ac7642 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -442,6 +442,8 @@ DEFINE_SYSREG_RW_FUNCS(cntp_cval_el0) DEFINE_SYSREG_READ_FUNC(cntpct_el0) DEFINE_SYSREG_RW_FUNCS(cnthctl_el2) +DEFINE_SYSREG_RW_FUNCS(vtcr_el2) + #define get_cntp_ctl_enable(x) (((x) >> CNTP_CTL_ENABLE_SHIFT) & \ CNTP_CTL_ENABLE_MASK) #define get_cntp_ctl_imask(x) (((x) >> CNTP_CTL_IMASK_SHIFT) & \ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c index 7ae853b76..c6544b45d 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c @@ -15,7 +15,7 @@ #include -void cm_prepare_el2_exit(uint32_t security_state); +void cm_prepare_el2_exit(void); /* Following contains the cpu context pointers. */ static void *bl1_cpu_context_ptr[2]; @@ -81,6 +81,9 @@ void bl1_prepare_next_image(unsigned int image_id) /* Allow platform to make change */ bl1_plat_set_ep_info(image_id, next_bl_ep); + /* Prepare context for the next EL */ + cm_prepare_el2_exit(); + /* Indicate that image is in execution state. */ desc->state = IMAGE_STATE_EXECUTED; diff --git a/plat/arm/board/fvp_r/fvp_r_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c index 678b8792c..d172d2d90 100644 --- a/plat/arm/board/fvp_r/fvp_r_context_mgmt.c +++ b/plat/arm/board/fvp_r/fvp_r_context_mgmt.c @@ -4,25 +4,50 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include -#include +#include -#include +/************************************************************ + * For R-class everything is in secure world. + * Prepare the CPU system registers for first entry into EL1 + ************************************************************/ +void cm_prepare_el2_exit(void) +{ + uint64_t hcr_el2 = 0U; + /* + * The use of ARMv8.3 pointer authentication (PAuth) is governed + * by fields in HCR_EL2, which trigger a 'trap to EL2' if not + * enabled. This register initialized at boot up, update PAuth + * bits. + * + * HCR_API_BIT: Set to one to disable traps to EL2 if lower ELs + * access PAuth registers + * + * HCR_APK_BIT: Set to one to disable traps to EL2 if lower ELs + * access PAuth instructions + */ + hcr_el2 = read_hcr_el2(); + write_hcr_el2(hcr_el2 | HCR_API_BIT | HCR_APK_BIT); -/******************************************************************************* - * File contains EL2 equivalents of EL3 functions from - * .../lib/el3_runtime/aarch64/context_mgmt.c - ******************************************************************************/ + /* + * Initialise CNTHCTL_EL2. All fields are architecturally UNKNOWN + * on reset and are set to zero except for field(s) listed below. + * + * CNTHCTL_EL2.EL1PCEN: Set to one to disable traps to EL2 + * if lower ELs accesses to the physical timer registers. + * + * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to EL2 + * if lower ELs access to the physical counter registers. + */ + write_cnthctl_el2(CNTHCTL_RESET_VAL | EL1PCEN_BIT | EL1PCTEN_BIT); -/******************************************************************************* - * Prepare the CPU system registers for first entry into secure or normal world - * - * The majority of the work needed is only for switching to non-secure, which - * is not available on v8-R64 cores, so this function is very simple. - ******************************************************************************/ -void cm_prepare_el2_exit(uint32_t security_state) -{ - cm_el1_sysregs_context_restore(security_state); - cm_set_next_eret_context(security_state); + /* + * On Armv8-R, the EL1&0 memory system architecture is configurable + * as a VMSA or PMSA. All the fields architecturally UNKNOWN on reset + * and are set to zero except for field listed below. + * + * VCTR_EL2.MSA: Set to one to ensure the VMSA is enabled so that + * rich OS can boot. + */ + write_vtcr_el2(VTCR_RESET_VAL | VTCR_EL2_MSA); } -- cgit v1.2.3 From c90fa47202b762fe8f54e9c0561e94d37907b6ad Mon Sep 17 00:00:00 2001 From: Bipin Ravi Date: Tue, 5 Oct 2021 15:57:06 -0500 Subject: fix(doc): fix TF-A v2.6 release date in the release information page Signed-off-by: Bipin Ravi Change-Id: If5482def6eb4fe23abe59ace09e9a1fbb891b117 --- docs/about/release-information.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/release-information.rst b/docs/about/release-information.rst index 3e8dd9100..b65571d51 100644 --- a/docs/about/release-information.rst +++ b/docs/about/release-information.rst @@ -46,7 +46,7 @@ depending on project requirement and partner feedback. +-----------------+---------------------------+------------------------------+ | v2.5 | 3rd week of May '21 | 5th week of Apr '21 | +-----------------+---------------------------+------------------------------+ -| v2.6 | 4th week of Oct '21 | 1st week of Oct '21 | +| v2.6 | 4th week of Nov '21 | 2nd week of Nov '21 | +-----------------+---------------------------+------------------------------+ Removal of Deprecated Interfaces -- cgit v1.2.3 From 5657decc7ffa1376c0a97b6d14ea1428877f5af4 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 10 Nov 2020 15:08:37 +0100 Subject: fix(plat/st): correct signedness comparison issue Add casts where required to avoid compialtion error when enabling -Wsign-compare in shared resources file. The assert is also corrected to match the correct range (change || to &&). Change-Id: Ie4c9c0c935d39ff9a2165b909172aacb3e94ab4d Signed-off-by: Yann Gautier --- plat/st/stm32mp1/stm32mp1_shared_resources.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/st/stm32mp1/stm32mp1_shared_resources.c b/plat/st/stm32mp1/stm32mp1_shared_resources.c index 208e34a8b..6b1bcaa13 100644 --- a/plat/st/stm32mp1/stm32mp1_shared_resources.c +++ b/plat/st/stm32mp1/stm32mp1_shared_resources.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -114,7 +114,7 @@ static unsigned int get_gpio_nbpin(unsigned int bank) if (bank != GPIO_BANK_Z) { int count = fdt_get_gpio_bank_pin_count(bank); - assert((count >= 0) || (count <= (GPIO_PIN_MAX + 1))); + assert((count >= 0) && ((unsigned int)count <= (GPIO_PIN_MAX + 1))); return (unsigned int)count; } @@ -163,7 +163,7 @@ static void register_periph(enum stm32mp_shres id, unsigned int state) if ((id >= STM32MP1_SHRES_GPIOZ(0)) && (id <= STM32MP1_SHRES_GPIOZ(7)) && - ((id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { + ((unsigned int)(id - STM32MP1_SHRES_GPIOZ(0)) >= get_gpioz_nbpin())) { ERROR("Invalid GPIO pin %u, %u pin(s) available\n", id - STM32MP1_SHRES_GPIOZ(0), get_gpioz_nbpin()); panic(); -- cgit v1.2.3 From 7684dddcfb14c45bad33b091410a0bf14a3a9830 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 7 Oct 2021 14:19:48 +0200 Subject: fix(stm32mp1): add bl prefix for internal linker script Due to patch [1], the bl prefix was removed from the build macros. It should then add explicitly when compiling stm32mp1.ld.S. [1] 434d0491c5 ("refactor(makefile): remove BL prefixes in build macros") Change-Id: I298dba2a7c958dd4ea6429c83ed4b1ee97e1735f Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 1c2c9f0a9..28463f1f5 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -323,7 +323,7 @@ ${BUILD_PLAT}/stm32mp1-%.o: ${BUILD_PLAT}/fdts/%-bl2.dtb plat/st/stm32mp1/stm32m -c plat/st/stm32mp1/stm32mp1.S -o $@ endif -$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,2)) +$(eval $(call MAKE_LD,${STM32_TF_LINKERFILE},plat/st/stm32mp1/stm32mp1.ld.S,bl2)) tf-a-%.elf: stm32mp1-%.o ${STM32_TF_LINKERFILE} @echo " LDS $<" -- cgit v1.2.3 From 9d38a3e698331e3c8192cc3e0cc8584e6ed987d9 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 7 Oct 2021 14:19:12 +0100 Subject: fix(arm_fgpa): allow build after MAKE_* changes Commit 434d0491c550 ("refactor(makefile): remove BL prefixes in build macros") changed the MAKE_S macro to expect "bl31" instead of just "31". Adjust our calls to MAKE_S and MAKE_LD to fix the build for arm_fpga. Change-Id: I2743e421c10eaecb39bfa4515ea049a1b8d18fcb Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/platform.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 1217425f0..901fabf37 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -117,9 +117,9 @@ BL31_SOURCES += common/fdt_wrappers.c \ ${FPGA_CPU_LIBS} \ ${FPGA_GIC_SOURCES} -$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,31)) -$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,31)) -$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,31)) +$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31)) +$(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31)) +$(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31)) bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld $(ECHO) " LD $@" -- cgit v1.2.3 From 21d2be83a2eabb328071e857e538ced3c8351874 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 10 Nov 2020 14:47:04 +0100 Subject: fix(lib/optee): correct signedness comparison Avoid compilation errors with -Wsign-compare : "comparison of integer expressions of different signedness" by changing type of num to uint32_t. And change init_load_addr check. Change-Id: I891e4a288a964ffdb52129813ba8652c5bcf85b2 Signed-off-by: Yann Gautier --- lib/optee/optee_utils.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/optee/optee_utils.c b/lib/optee/optee_utils.c index d090b3826..72979cd9d 100644 --- a/lib/optee/optee_utils.c +++ b/lib/optee/optee_utils.c @@ -82,11 +82,14 @@ static int parse_optee_image(image_info_t *image_info, init_size = image->size; /* - * -1 indicates loader decided address; take our pre-mapped area - * for current image since arm-tf could not allocate memory dynamically + * image->load_addr_hi & image->load_addr_lo set to UINT32_MAX indicate + * loader decided address; take our pre-mapped area for current image + * since arm-tf could not allocate memory dynamically */ - if (init_load_addr == -1) + if ((image->load_addr_hi == UINT32_MAX) && + (image->load_addr_lo == UINT32_MAX)) { init_load_addr = image_info->image_base; + } /* Check that the default end address doesn't overflow */ if (check_uptr_overflow(image_info->image_base, @@ -138,7 +141,8 @@ int parse_optee_header(entry_point_info_t *header_ep, { optee_header_t *header; - int num, ret; + uint32_t num; + int ret; assert(header_ep); header = (optee_header_t *)header_ep->pc; @@ -181,7 +185,7 @@ int parse_optee_header(entry_point_info_t *header_ep, } /* Parse OPTEE image */ - for (num = 0; num < header->nb_images; num++) { + for (num = 0U; num < header->nb_images; num++) { if (header->optee_image_list[num].image_id == OPTEE_PAGER_IMAGE_ID) { ret = parse_optee_image(pager_image_info, -- cgit v1.2.3 From fb90cfd4eee504f1d16aa143728af427dc6e0ed8 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Sun, 26 Sep 2021 15:51:15 +0800 Subject: fix(nxp/scfg): fix endianness checking It is a typo to check NXP_GUR_LE in scfg driver. Signed-off-by: Jiafei Pan Change-Id: I4b952bf4136dd626d88fc4797dba2be445395801 --- include/drivers/nxp/dcfg/scfg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drivers/nxp/dcfg/scfg.h b/include/drivers/nxp/dcfg/scfg.h index b6e3df566..ef6ed6be8 100644 --- a/include/drivers/nxp/dcfg/scfg.h +++ b/include/drivers/nxp/dcfg/scfg.h @@ -44,7 +44,7 @@ #define scfg_clrbits32(a, v) mmio_clrbits_32((uintptr_t)(a), v) #define scfg_clrsetbits32(a, clear, set) \ mmio_clrsetbits_32((uintptr_t)(a), clear, set) -#elif defined(NXP_GUR_LE) +#elif defined(NXP_SCFG_LE) #define scfg_in32(a) mmio_read_32((uintptr_t)(a)) #define scfg_out32(a, v) mmio_write_32((uintptr_t)(a), v) #define scfg_setbits32(a, v) mmio_setbits_32((uintptr_t)(a), v) -- cgit v1.2.3 From 2475f63bdec6c24c13f7d6ec7f70275b1bde5c15 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Sun, 26 Sep 2021 15:55:51 +0800 Subject: fix(plat/nxp/ls1028a): define endianness of scfg and gpio Define endianness of scfg and gpio. Signed-off-by: Jiafei Pan Change-Id: Ifa18b4fcfc45154c23d54692b374bab293c51a04 --- plat/nxp/soc-ls1028a/soc.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plat/nxp/soc-ls1028a/soc.def b/plat/nxp/soc-ls1028a/soc.def index e13398289..c23c1bb30 100644 --- a/plat/nxp/soc-ls1028a/soc.def +++ b/plat/nxp/soc-ls1028a/soc.def @@ -88,6 +88,8 @@ NXP_SNVS_ENDIANNESS := LE NXP_ESDHC_ENDIANNESS := LE NXP_QSPI_ENDIANNESS := LE NXP_FSPI_ENDIANNESS := LE +NXP_SCFG_ENDIANNESS := LE +NXP_GPIO_ENDIANNESS := LE NXP_SFP_VER := 3_4 -- cgit v1.2.3 From 3239a17561c124df7095391c0d64e86910660cdc Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 27 Sep 2021 11:47:11 +0800 Subject: fix(drivers/nxp/sfp): fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix compile warning that ‘mask’ may be used uninitialized. Signed-off-by: Jiafei Pan Change-Id: I75a443dbc36d7bd174fe317616fd95cd096306fc --- drivers/nxp/sfp/fuse_prov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nxp/sfp/fuse_prov.c b/drivers/nxp/sfp/fuse_prov.c index 4d30f5f28..165474fb8 100644 --- a/drivers/nxp/sfp/fuse_prov.c +++ b/drivers/nxp/sfp/fuse_prov.c @@ -326,7 +326,7 @@ static int prog_ospr1(struct fuse_hdr_t *fuse_hdr, struct sfp_ccsr_regs_t *sfp_ccsr_regs) { int ret; - uint32_t mask; + uint32_t mask = 0; #ifdef NXP_SFP_VER_3_4 if (((fuse_hdr->flags >> FLAG_MC_SHIFT) & 0x1) != 0) { -- cgit v1.2.3 From a0da9c4bd296ec1a47683a1ee05f5d1ed71828c7 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 27 Sep 2021 11:50:08 +0800 Subject: fix(plat/nxp/ls1028a): fix compile error when enable fuse provision Fix the error that no "gpio_init_data" is defined when build with "FUSE_PROG=1". Signed-off-by: Jiafei Pan Change-Id: I0ba8005725fe33c6d8e68b4d52539f5d5d749f1a --- plat/nxp/soc-ls1028a/soc.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plat/nxp/soc-ls1028a/soc.c b/plat/nxp/soc-ls1028a/soc.c index 4f6715484..edfd6573d 100644 --- a/plat/nxp/soc-ls1028a/soc.c +++ b/plat/nxp/soc-ls1028a/soc.c @@ -16,6 +16,9 @@ #include #include #include +#ifdef POLICY_FUSE_PROVISION +#include +#endif #if TRUSTED_BOARD_BOOT #include #endif @@ -81,6 +84,15 @@ unsigned int plat_get_syscnt_freq2(void) } #ifdef IMAGE_BL2 + +#ifdef POLICY_FUSE_PROVISION +static gpio_init_info_t gpio_init_data = { + .gpio1_base_addr = NXP_GPIO1_ADDR, + .gpio2_base_addr = NXP_GPIO2_ADDR, + .gpio3_base_addr = NXP_GPIO3_ADDR, +}; +#endif + void soc_preload_setup(void) { } -- cgit v1.2.3 From 8bfb16813aff9b3dcbeaa2f77027d44b97f04b6d Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 27 Sep 2021 12:18:41 +0800 Subject: feat(plat/nxp/common): add EESR register definition Add OCRAM bit mask to be used in OCRAM driver. Signed-off-by: Jiafei Pan Change-Id: If82542cc6c1c243d8f998b193954dd72312ee1a4 --- plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h | 7 ++++++- plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h index 789b112a6..84f07e635 100644 --- a/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h +++ b/plat/nxp/common/include/default/ch_2/soc_default_helper_macros.h @@ -56,6 +56,11 @@ #define RCPM_POWMGTCSR_OFFSET 0x130 #define RCPM_IPPDEXPCR0_OFFSET 0x140 #define RCPM_POWMGTCSR_LPM20_REQ 0x00100000 -#endif +#endif /* NXP_RCPM_ADDR */ + +#define DCFG_SBEESR2_ADDR 0x20140534 +#define DCFG_MBEESR2_ADDR 0x20140544 +/* SBEESR and MBEESR bit mask */ +#define OCRAM_EESR_MASK 0x00000060 #endif /* SOC_DEFAULT_HELPER_MACROS_H */ diff --git a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h index 8de516efc..1edd28d2a 100644 --- a/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h +++ b/plat/nxp/common/include/default/ch_3_2/soc_default_helper_macros.h @@ -79,4 +79,9 @@ #define ENABLE_WUO 0x10 #endif /* NXP_CCN_ADDR */ +#define DCFG_SBEESR2_ADDR 0x00100534 +#define DCFG_MBEESR2_ADDR 0x00100544 +/* SBEESR and MBEESR bit mask */ +#define OCRAM_EESR_MASK 0x00000008 + #endif /* SOC_DEFAULT_HELPER_MACROS_H */ -- cgit v1.2.3 From 10b1e13bd200849ff134dd8d2fde341a8526f563 Mon Sep 17 00:00:00 2001 From: Jiafei Pan Date: Mon, 27 Sep 2021 12:20:09 +0800 Subject: feat(nxp/common/ocram): add driver for OCRAM initialization In order to enable OCRAM ECC, it need to be initialized with 64-bit writes and then a write performed to address 0x0010_0534 with the value 0x0000_0008. Signed-off-by: Jiafei Pan Change-Id: Id7d4f5df65ca52f24e9251c08a75ad2006451b95 --- plat/nxp/common/ocram/aarch64/ocram.S | 71 ++++++++++++++++++++++ plat/nxp/common/ocram/ocram.h | 13 ++++ plat/nxp/common/ocram/ocram.mk | 14 +++++ plat/nxp/common/plat_make_helper/soc_common_def.mk | 5 ++ 4 files changed, 103 insertions(+) create mode 100644 plat/nxp/common/ocram/aarch64/ocram.S create mode 100644 plat/nxp/common/ocram/ocram.h create mode 100644 plat/nxp/common/ocram/ocram.mk diff --git a/plat/nxp/common/ocram/aarch64/ocram.S b/plat/nxp/common/ocram/aarch64/ocram.S new file mode 100644 index 000000000..ec5334143 --- /dev/null +++ b/plat/nxp/common/ocram/aarch64/ocram.S @@ -0,0 +1,71 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +.global ocram_init + +/* + * void ocram_init(uintptr_t start_addr, size_t size) + * + * This function will do OCRAM ECC. + * OCRAM is initialized with 64-bit writes and then a write + * performed to address 0x0010_0534 with the value 0x0000_0008. + * + * x0: start_addr + * x1: size in bytes + * Called from C + */ + +func ocram_init + /* save the aarch32/64 non-volatile registers */ + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + stp x8, x9, [sp, #-16]! + stp x10, x11, [sp, #-16]! + stp x12, x13, [sp, #-16]! + stp x18, x30, [sp, #-16]! + + /* convert bytes to 64-byte chunks */ + lsr x1, x1, #6 +1: + /* for each location, read and write-back */ + dc ivac, x0 + dsb sy + ldp x4, x5, [x0] + ldp x6, x7, [x0, #16] + ldp x8, x9, [x0, #32] + ldp x10, x11, [x0, #48] + stp x4, x5, [x0] + stp x6, x7, [x0, #16] + stp x8, x9, [x0, #32] + stp x10, x11, [x0, #48] + dc cvac, x0 + + sub x1, x1, #1 + cbz x1, 2f + add x0, x0, #64 + b 1b +2: + /* Clear OCRAM ECC status bit in SBEESR2 and MBEESR2 */ + ldr w1, =OCRAM_EESR_MASK + ldr x0, =DCFG_SBEESR2_ADDR + str w1, [x0] + ldr x0, =DCFG_MBEESR2_ADDR + str w1, [x0] + + /* restore the aarch32/64 non-volatile registers */ + ldp x18, x30, [sp], #16 + ldp x12, x13, [sp], #16 + ldp x10, x11, [sp], #16 + ldp x8, x9, [sp], #16 + ldp x6, x7, [sp], #16 + ldp x4, x5, [sp], #16 + ret +endfunc ocram_init diff --git a/plat/nxp/common/ocram/ocram.h b/plat/nxp/common/ocram/ocram.h new file mode 100644 index 000000000..479de61ac --- /dev/null +++ b/plat/nxp/common/ocram/ocram.h @@ -0,0 +1,13 @@ +/* + * Copyright 2021 NXP + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef OCRAM_H +#define OCRAM_H + +void ocram_init(uintptr_t start_addr, size_t size); + +#endif /* OCRAM_H */ diff --git a/plat/nxp/common/ocram/ocram.mk b/plat/nxp/common/ocram/ocram.mk new file mode 100644 index 000000000..c77bd4adb --- /dev/null +++ b/plat/nxp/common/ocram/ocram.mk @@ -0,0 +1,14 @@ +# +# Copyright 2021 NXP +# +# SPDX-License-Identifier: BSD-3-Clause +# +# + +PLAT_OCRAM_PATH := $(PLAT_COMMON_PATH)/ocram + +OCRAM_SOURCES := ${PLAT_OCRAM_PATH}/$(ARCH)/ocram.S + +BL2_SOURCES += ${OCRAM_SOURCES} + +PLAT_INCLUDES += -I${PLAT_COMMON_PATH}/ocram diff --git a/plat/nxp/common/plat_make_helper/soc_common_def.mk b/plat/nxp/common/plat_make_helper/soc_common_def.mk index fdd724951..22cd39aef 100644 --- a/plat/nxp/common/plat_make_helper/soc_common_def.mk +++ b/plat/nxp/common/plat_make_helper/soc_common_def.mk @@ -112,3 +112,8 @@ endif ifneq (${PLAT_XLAT_TABLES_DYNAMIC},) $(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC)) endif + +ifeq (${OCRAM_ECC_EN},yes) +$(eval $(call add_define,CONFIG_OCRAM_ECC_EN)) +include ${PLAT_COMMON_PATH}/ocram/ocram.mk +endif -- cgit v1.2.3 From 0a6e2147e7ac3ead068853f1258f31a15670ac99 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Mon, 11 Oct 2021 16:25:49 +0200 Subject: plat/marvell/a8k: add Globalscale Mochabin support Add support for Globalscale MOCHAbin board. Its based on Armada 7040 SoC and ships in multiple DRAM options: * 2GB DDR4 (1CS) * 4GB DDR4 (1CS) * 8GB DDR4 (2CS) Since it ships in multiple DRAM configurations, an Armada 3k style DDR_TOPOLOGY variable is added. Currently, this only has effect on the MOCHAbin, but I expect more boards with multiple DRAM sizes to be supported. Signed-off-by: Robert Marko Change-Id: I8a1ec9268fed34f6a81c5cbf1e891f638d461305 --- docs/plat/marvell/armada/build.rst | 11 + .../armada/a8k/a70x0_mochabin/board/dram_port.c | 227 +++++++++++++++++++++ .../a8k/a70x0_mochabin/board/marvell_plat_config.c | 145 +++++++++++++ .../a8k/a70x0_mochabin/board/phy-porting-layer.h | 87 ++++++++ plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h | 15 ++ plat/marvell/armada/a8k/a70x0_mochabin/platform.mk | 20 ++ plat/marvell/armada/a8k/common/a8k_common.mk | 4 + 7 files changed, 509 insertions(+) create mode 100644 plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c create mode 100644 plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c create mode 100644 plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h create mode 100644 plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h create mode 100644 plat/marvell/armada/a8k/a70x0_mochabin/platform.mk diff --git a/docs/plat/marvell/armada/build.rst b/docs/plat/marvell/armada/build.rst index b12514469..6872f56a1 100644 --- a/docs/plat/marvell/armada/build.rst +++ b/docs/plat/marvell/armada/build.rst @@ -58,6 +58,7 @@ There are several build options: - a3700 - A3720 DB, EspressoBin and Turris MOX - a70x0 - a70x0_amc - AMC board + - a70x0_mochabin - Globalscale MOCHAbin - a80x0 - a80x0_mcbin - MacchiatoBin - a80x0_puzzle - IEI Puzzle-M801 @@ -150,6 +151,16 @@ A7K/8K/CN913x specific build options: Specify path to the MSS fimware image binary which will run on Cortex-M3 coprocessor. It is available in Marvell binaries-marvell git repository. Required when ``MSS_SUPPORT=1``. +Globalscale MOCHAbin specific build options: + +- DDR_TOPOLOGY + + The DDR topology map index/name, default is 0. + + Supported Options: + - 0 - DDR4 1CS 2GB + - 1 - DDR4 1CS 4GB + - 2 - DDR4 2CS 8GB Armada37x0 specific build options: diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c b/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c new file mode 100644 index 000000000..68d335b63 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/dram_port.c @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2021 Sartura Ltd. + * Copyright (C) 2021 Globalscale technologies, Inc. + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include +#include + +#include +#include + +/* + * This function may modify the default DRAM parameters + * based on information received from SPD or bootloader + * configuration located on non volatile storage + */ +void plat_marvell_dram_update_topology(void) +{ +} + +/* + * This struct provides the DRAM training code with + * the appropriate board DRAM configuration + */ +#if DDR_TOPOLOGY == 0 +static struct mv_ddr_topology_map board_topology_map_2g = { +/* 1CS 4Gb x4 devices of Samsung K4A4G085WF */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0} }, + SPEED_BIN_DDR_2400R, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_4GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + BUS_MASK_32BIT, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; +#endif + +#if DDR_TOPOLOGY == 1 +static struct mv_ddr_topology_map board_topology_map_4g = { +/* 1CS 8Gb x4 devices of Samsung K4A8G085WC-BCTD */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0}, + {0x1, 0x2, 0, 0} }, + SPEED_BIN_DDR_2400R, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_8GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + BUS_MASK_32BIT, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; +#endif + +#if DDR_TOPOLOGY == 2 +static struct mv_ddr_topology_map board_topology_map_8g = { +/* 2CS 8Gb x8 devices of Micron MT40A1G8WE-083E IT */ + DEBUG_LEVEL_ERROR, + 0x1, /* active interfaces */ + /* cs_mask, mirror, dqs_swap, ck_swap X subphys */ + { { { {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0}, + {0x3, 0x2, 0, 0} }, + SPEED_BIN_DDR_2400R, /* speed_bin */ + MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */ + MV_DDR_DIE_CAP_8GBIT, /* die capacity */ + MV_DDR_FREQ_SAR, /* frequency */ + 0, 0, /* cas_l, cas_wl */ + MV_DDR_TEMP_LOW} }, /* temperature */ + BUS_MASK_32BIT, /* subphys mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + NOT_COMBINED, /* ddr twin-die combined*/ + { {0} }, /* raw spd data */ + {0}, /* timing parameters */ + { /* electrical configuration */ + { /* memory electrical configuration */ + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */ + { + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */ + }, + { + MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */ + MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */ + }, + MV_DDR_DIC_RZQ_DIV7 /* dic */ + }, + { /* phy electrical configuration */ + MV_DDR_OHM_30, /* data_drv_p */ + MV_DDR_OHM_30, /* data_drv_n */ + MV_DDR_OHM_30, /* ctrl_drv_p */ + MV_DDR_OHM_30, /* ctrl_drv_n */ + { + MV_DDR_OHM_60, /* odt_p 1cs */ + MV_DDR_OHM_120 /* odt_p 2cs */ + }, + { + MV_DDR_OHM_60, /* odt_n 1cs */ + MV_DDR_OHM_120 /* odt_n 2cs */ + }, + }, + { /* mac electrical configuration */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */ + MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */ + MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */ + }, + } +}; +#endif + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) +{ +/* a70x0_mochabin board supports 3 DDR4 models (2G/1CS, 4G/1CS, 8G/2CS) */ +#if DDR_TOPOLOGY == 0 + return &board_topology_map_2g; +#elif DDR_TOPOLOGY == 1 + return &board_topology_map_4g; +#elif DDR_TOPOLOGY == 2 + return &board_topology_map_8g; +#else + #error "Unknown DDR topology" +#endif +} diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c b/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c new file mode 100644 index 000000000..1ed63237a --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/marvell_plat_config.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2021 Sartura Ltd. + * Copyright (C) 2021 Globalscale technologies, Inc. + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +/* + * If bootrom is currently at BLE there's no need to include the memory + * maps structure at this point + */ +#include +#ifndef IMAGE_BLE + +/***************************************************************************** + * AMB Configuration + ***************************************************************************** + */ +struct addr_map_win amb_memory_map[] = { + /* CP0 SPI1 CS0 Direct Mode access */ + {0xf900, 0x1000000, AMB_SPI1_CS0_ID}, +}; + +int marvell_get_amb_memory_map(struct addr_map_win **win, + uint32_t *size, uintptr_t base) +{ + *win = amb_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(amb_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * IO_WIN Configuration + ***************************************************************************** + */ +struct addr_map_win io_win_memory_map[] = { +#ifndef IMAGE_BLE + /* MCI 0 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID}, + /* MCI 1 indirect window */ + {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID}, +#endif +}; + +uint32_t marvell_get_io_win_gcr_target(int ap_index) +{ + return PIDI_TID; +} + +int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = io_win_memory_map; + if (*win == NULL) + *size = 0; + else + *size = ARRAY_SIZE(io_win_memory_map); + + return 0; +} + +#ifndef IMAGE_BLE +/***************************************************************************** + * IOB Configuration + ***************************************************************************** + */ +struct addr_map_win iob_memory_map[] = { + /* PEX1_X1 window */ + {0x00000000f7000000, 0x1000000, PEX1_TID}, + /* PEX2_X1 window */ + {0x00000000f8000000, 0x1000000, PEX2_TID}, + {0x00000000c0000000, 0x30000000, PEX2_TID}, + {0x0000000800000000, 0x100000000, PEX2_TID}, + /* PEX0_X4 window */ + {0x00000000f6000000, 0x1000000, PEX0_TID}, + /* SPI1_CS0 (RUNIT) window */ + {0x00000000f9000000, 0x1000000, RUNIT_TID}, +}; + +int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size, + uintptr_t base) +{ + *win = iob_memory_map; + *size = ARRAY_SIZE(iob_memory_map); + + return 0; +} +#endif + +/***************************************************************************** + * CCU Configuration + ***************************************************************************** + */ +struct addr_map_win ccu_memory_map[] = { /* IO window */ +#ifdef IMAGE_BLE + {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */ +#else +#if LLC_SRAM + /* This entry is prepared for OP-TEE OS that enables the LLC SRAM + * and changes the window target to SRAM_TID. + */ + {PLAT_MARVELL_LLC_SRAM_BASE, PLAT_MARVELL_LLC_SRAM_SIZE, DRAM_0_TID}, +#endif + {0x00000000f2000000, 0xe000000, IO_0_TID}, + {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */ + {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */ +#endif +}; + +uint32_t marvell_get_ccu_gcr_target(int ap) +{ + return DRAM_0_TID; +} + +int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win, + uint32_t *size) +{ + *win = ccu_memory_map; + *size = ARRAY_SIZE(ccu_memory_map); + + return 0; +} + +#ifdef IMAGE_BLE +/***************************************************************************** + * SKIP IMAGE Configuration + ***************************************************************************** + */ +#if PLAT_RECOVERY_IMAGE_ENABLE +void *plat_marvell_get_skip_image_data(void) +{ + /* No recovery button on a70x0_mochabin board */ + return NULL; +} +#endif +#endif diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h b/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h new file mode 100644 index 000000000..ab76c3105 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_mochabin/board/phy-porting-layer.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2021 Sartura Ltd. + * Copyright (C) 2021 Globalscale technologies, Inc. + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef __PHY_PORTING_LAYER_H +#define __PHY_PORTING_LAYER_H + +#define MAX_LANE_NR 6 + +static const struct xfi_params + xfi_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 */ + { 0 }, /* Comphy1 */ + { 0 }, /* Comphy2 */ + { 0 }, /* Comphy3 */ + { .g1_ffe_res_sel = 0x3, .g1_ffe_cap_sel = 0xf, .align90 = 0x60, + .g1_dfe_res = 0x1, .g1_amp = 0x1c, .g1_emph = 0xe, + .g1_emph_en = 0x1, .g1_tx_amp_adj = 0x1, .g1_tx_emph_en = 0x1, + .g1_tx_emph = 0x0, .g1_rx_selmuff = 0x1, .g1_rx_selmufi = 0x0, + .g1_rx_selmupf = 0x2, .g1_rx_selmupi = 0x2, + .valid = 1 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + }, +}; + +static const struct sata_params + sata_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + /* AP0 */ + { + /* CP 0 */ + { + { 0 }, /* Comphy0 */ + { 0 }, /* Comphy1 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, + .valid = 0x1 + }, /* Comphy2 */ + { .g1_amp = 0x8, .g2_amp = 0xa, .g3_amp = 0x1e, + .g1_emph = 0x1, .g2_emph = 0x2, .g3_emph = 0xe, + .g1_emph_en = 0x1, .g2_emph_en = 0x1, .g3_emph_en = 0x1, + .g1_tx_amp_adj = 0x1, .g2_tx_amp_adj = 0x1, .g3_tx_amp_adj = 0x1, + .g1_tx_emph_en = 0x0, .g2_tx_emph_en = 0x0, .g3_tx_emph_en = 0x0, + .g1_tx_emph = 0x1, .g2_tx_emph = 0x1, .g3_tx_emph = 0x1, + .g3_dfe_res = 0x1, .g3_ffe_res_sel = 0x4, .g3_ffe_cap_sel = 0xf, + .align90 = 0x61, + .g1_rx_selmuff = 0x3, .g2_rx_selmuff = 0x3, .g3_rx_selmuff = 0x3, + .g1_rx_selmufi = 0x0, .g2_rx_selmufi = 0x0, .g3_rx_selmufi = 0x3, + .g1_rx_selmupf = 0x1, .g2_rx_selmupf = 0x1, .g3_rx_selmupf = 0x2, + .g1_rx_selmupi = 0x0, .g2_rx_selmupi = 0x0, .g3_rx_selmupi = 0x2, + .polarity_invert = COMPHY_POLARITY_NO_INVERT, + .valid = 0x1 + }, /* Comphy3 */ + { 0 }, /* Comphy4 */ + { 0 }, /* Comphy5 */ + }, + }, +}; + +static const struct usb_params + usb_static_values_tab[AP_NUM][CP_NUM][MAX_LANE_NR] = { + [0 ... AP_NUM-1][0 ... CP_NUM-1][0 ... MAX_LANE_NR-1] = { + .polarity_invert = COMPHY_POLARITY_NO_INVERT + }, +}; + +#endif /* __PHY_PORTING_LAYER_H */ diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h b/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h new file mode 100644 index 000000000..768f73596 --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_mochabin/mvebu_def.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2021 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#ifndef MVEBU_DEF_H +#define MVEBU_DEF_H + +#include + +#define CP_COUNT 1 /* A70x0 has single CP0 */ + +#endif /* MVEBU_DEF_H */ diff --git a/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk b/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk new file mode 100644 index 000000000..2495591ae --- /dev/null +++ b/plat/marvell/armada/a8k/a70x0_mochabin/platform.mk @@ -0,0 +1,20 @@ +# +# Copyright (C) 2021 Marvell International Ltd. +# +# SPDX-License-Identifier: BSD-3-Clause +# https://spdx.org/licenses +# + +PCI_EP_SUPPORT := 0 + +CP_NUM := 1 +$(eval $(call add_define,CP_NUM)) + +DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg + +MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c + +BOARD_DIR := $(shell dirname $(lastword $(MAKEFILE_LIST))) +include plat/marvell/armada/a8k/common/a8k_common.mk + +include plat/marvell/armada/common/marvell_common.mk diff --git a/plat/marvell/armada/a8k/common/a8k_common.mk b/plat/marvell/armada/a8k/common/a8k_common.mk index 9474d085d..4d8a87fd1 100644 --- a/plat/marvell/armada/a8k/common/a8k_common.mk +++ b/plat/marvell/armada/a8k/common/a8k_common.mk @@ -75,6 +75,10 @@ endif # This define specifies DDR type for BLE $(eval $(call add_define,CONFIG_DDR4)) +# This define specifies DDR topology for BLE +DDR_TOPOLOGY ?= 0 +$(eval $(call add_define,DDR_TOPOLOGY)) + MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/v2/gicv2_helpers.c \ -- cgit v1.2.3 From bd2ad12ef10f558a5b15f5768b66e7b2606c6498 Mon Sep 17 00:00:00 2001 From: Maxim Uvarov Date: Thu, 8 Jul 2021 11:59:18 +0300 Subject: fix(plat/qemu): reboot/shutdown with low to high gpio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use low to high gpio sequence to reboot/shutdown qemu machine. Use low to high gpio pins level change which will cause an interrupt in qemu virt platform. This change will supported with next qemu 6.1 release once patchset: hw/arm: Make virt board secure powerdown/reset work will be merged. Signed-off-by: Maxim Uvarov CC: Peter Maydell Change-Id: I70979517358c3b587722b2dcb33f63d29bf79d9b --- plat/qemu/common/qemu_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/qemu/common/qemu_pm.c b/plat/qemu/common/qemu_pm.c index c4ffcf922..c2b5091d4 100644 --- a/plat/qemu/common/qemu_pm.c +++ b/plat/qemu/common/qemu_pm.c @@ -208,8 +208,8 @@ static void __dead2 qemu_system_off(void) #ifdef SECURE_GPIO_BASE ERROR("QEMU System Power off: with GPIO.\n"); gpio_set_direction(SECURE_GPIO_POWEROFF, GPIO_DIR_OUT); - gpio_set_value(SECURE_GPIO_POWEROFF, GPIO_LEVEL_HIGH); gpio_set_value(SECURE_GPIO_POWEROFF, GPIO_LEVEL_LOW); + gpio_set_value(SECURE_GPIO_POWEROFF, GPIO_LEVEL_HIGH); #else semihosting_exit(ADP_STOPPED_APPLICATION_EXIT, 0); ERROR("QEMU System Off: semihosting call unexpectedly returned.\n"); @@ -222,8 +222,8 @@ static void __dead2 qemu_system_reset(void) ERROR("QEMU System Reset: with GPIO.\n"); #ifdef SECURE_GPIO_BASE gpio_set_direction(SECURE_GPIO_RESET, GPIO_DIR_OUT); - gpio_set_value(SECURE_GPIO_RESET, GPIO_LEVEL_HIGH); gpio_set_value(SECURE_GPIO_RESET, GPIO_LEVEL_LOW); + gpio_set_value(SECURE_GPIO_RESET, GPIO_LEVEL_HIGH); #else ERROR("QEMU System Reset: operation not handled.\n"); #endif -- cgit v1.2.3 From be42c4b4bf3c44f2970b7a1658c46b8d5863cad1 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 27 Sep 2021 18:16:52 +0100 Subject: fix(plat/arm): remove unused memory node memory information is passed to kernel via u-boot. Signed-off-by: Usama Arif Change-Id: I3ef31047f92d96302cc98257e965751929a08541 --- fdts/tc.dts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fdts/tc.dts b/fdts/tc.dts index f66d55670..31fcfe2de 100644 --- a/fdts/tc.dts +++ b/fdts/tc.dts @@ -161,11 +161,6 @@ }; - memory@80000000 { - device_type = "memory"; - reg = <0x0 0x80000000 0x0 0x7d000000>; - }; - reserved-memory { #address-cells = <2>; #size-cells = <2>; -- cgit v1.2.3 From 76b4a6bb208c22b1c5971964a209ff7d54982348 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 27 Sep 2021 18:18:01 +0100 Subject: feat(plat/arm): Add DRAM2 to TZC non-secure region This allows to increase the total DRAM to 8GB. Signed-off-by: Usama Arif Change-Id: I6daaed9a0b7a11d665b2f56e6432a1ef87bfaa38 --- plat/arm/board/tc/include/platform_def.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h index ccabced9e..745d91cab 100644 --- a/plat/arm/board/tc/include/platform_def.h +++ b/plat/arm/board/tc/include/platform_def.h @@ -185,6 +185,7 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) #define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) +#define PLAT_ARM_DRAM2_END (PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL) #define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) @@ -260,13 +261,15 @@ /* * The first region below, TC_TZC_DRAM1_BASE (0xfd000000) to * ARM_SCP_TZC_DRAM1_END (0xffffffff) will mark the last 48 MB of DRAM as - * secure. The second region gives non secure access to rest of DRAM. + * secure. The second and third regions gives non secure access to rest of DRAM. */ -#define TC_TZC_REGIONS_DEF \ - {TC_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \ - TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \ - {TC_NS_DRAM1_BASE, TC_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ - PLAT_ARM_TZC_NS_DEV_ACCESS} +#define TC_TZC_REGIONS_DEF \ + {TC_TZC_DRAM1_BASE, ARM_SCP_TZC_DRAM1_END, \ + TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {TC_NS_DRAM1_BASE, TC_NS_DRAM1_END, ARM_TZC_NS_DRAM_S_ACCESS, \ + PLAT_ARM_TZC_NS_DEV_ACCESS}, \ + {PLAT_ARM_DRAM2_BASE, PLAT_ARM_DRAM2_END, \ + ARM_TZC_NS_DRAM_S_ACCESS, PLAT_ARM_TZC_NS_DEV_ACCESS} /* virtual address used by dynamic mem_protect for chunk_base */ #define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000) -- cgit v1.2.3 From 0f3a1221093256999af5f2a80e9b3d7231b9f5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 12 Oct 2021 14:53:25 +0200 Subject: fix(drivers/marvell/comphy-3700): configure phy selector also for PCIe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mvebu_a3700_comphy_pcie_power_on() function does not configure the PHY selector explicitly, it relies on the register default value. Configure the PHY selector just in case someone changed the default value. Signed-off-by: Pali Rohár Change-Id: I54048b4bb7a5eced36f7fe6592ebe108f978fff0 --- drivers/marvell/comphy/phy-comphy-3700.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c index 0ad14a800..a3e414c4b 100644 --- a/drivers/marvell/comphy/phy-comphy-3700.c +++ b/drivers/marvell/comphy/phy-comphy-3700.c @@ -815,6 +815,12 @@ static int mvebu_a3700_comphy_pcie_power_on(uint8_t comphy_index, debug_enter(); + /* Configure phy selector for PCIe */ + ret = mvebu_a3700_comphy_set_phy_selector(comphy_index, comphy_mode); + if (ret) { + return ret; + } + /* 1. Enable max PLL. */ reg_set16(LANE_CFG1_ADDR(PCIE) + COMPHY_SD_ADDR, USE_MAX_PLL_RATE_EN, USE_MAX_PLL_RATE_EN); -- cgit v1.2.3 From 4a24707f948c7a9762a7bdba3256b47269841369 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 1 Jul 2021 14:13:09 +0200 Subject: refactor(measured boot): rename tpm_record_measurement() tpm_record_measurement() function name suggests that: - It only records a measurement but does not compute it. This is not the case, the function does both. - It stores this measurement into a TPM (discrete chip or fTPM). This is not the case either, the measurement is just stored into the event log, which is a data structure hold in memory, there is no TPM involvement here. To better convey the intent of the function, rename it into event_log_measure_and_record(). Change-Id: I0102eeda477d6c6761151ac96759b31b6997e9fb Signed-off-by: Sandrine Bailleux --- drivers/measured_boot/event_log.c | 6 +++--- include/drivers/measured_boot/event_log.h | 6 +++--- plat/arm/board/fvp/fvp_bl2_setup.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log.c index 0157b0300..634ab7486 100644 --- a/drivers/measured_boot/event_log.c +++ b/drivers/measured_boot/event_log.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -236,8 +236,8 @@ void event_log_init(void) * 0 = success * < 0 = error */ -int tpm_record_measurement(uintptr_t data_base, uint32_t data_size, - uint32_t data_id) +int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id) { const image_data_t *data_ptr = plat_data_ptr->images_data; unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; diff --git a/include/drivers/measured_boot/event_log.h b/include/drivers/measured_boot/event_log.h index efde11762..b0ce6a762 100644 --- a/include/drivers/measured_boot/event_log.h +++ b/include/drivers/measured_boot/event_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -92,6 +92,6 @@ void event_log_init(void); int event_log_finalise(uint8_t **log_addr, size_t *log_size); void dump_event_log(uint8_t *log_addr, size_t log_size); const measured_boot_data_t *plat_get_measured_boot_data(void); -int tpm_record_measurement(uintptr_t data_base, uint32_t data_size, - uint32_t data_id); +int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id); #endif /* EVENT_LOG_H */ diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index f2f21432d..abf7988e7 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -86,8 +86,8 @@ static int fvp_bl2_plat_handle_post_image_load(unsigned int image_id) if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) { /* Calculate image hash and record data in Event Log */ - err = tpm_record_measurement(info.image_base, - info.image_size, image_id); + err = event_log_measure_and_record(info.image_base, + info.image_size, image_id); if (err != 0) { ERROR("%s%s image id %u (%i)\n", "BL2: Failed to ", "record", image_id, err); -- cgit v1.2.3 From 47bf3ac31ec84d4b221fdef760c04b5f4416cba4 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 6 Aug 2021 09:26:20 +0100 Subject: feat(measured boot): move init and teardown functions to platform layer Right now, the measured boot driver is strongly coupled with the TCG event log driver. It would not be possible to push the measurements somewhere else, for instance to a physical TPM. To enable this latter use case, turn the driver's init and teardown functions into platform hooks. Call them bl2_plat_mboot_init()/finish(). This allows each platform to implement them appropriately, depending on the type of measured boot backend they use. For example, on a platform with a physical TPM, the plat_mboot_init() hook would startup the TPM and setup it underlying bus (e.g. SPI). Move the current implementation of the init and teardown function to the FVP platform layer. Finally move the conditional compilation logic (#if MEASURED_BOOT) out of bl2_main() to improve its readability. Provide a dummy implementation in the case measured boot is not included in the build. Change-Id: Ib6474cb5a9c1e3d4a30c7f228431b22d1a6e85e3 Signed-off-by: Sandrine Bailleux Signed-off-by: Manish V Badarkhe --- bl2/bl2_main.c | 18 ++++--------- drivers/measured_boot/measured_boot.c | 39 --------------------------- drivers/measured_boot/measured_boot.mk | 7 +++-- include/drivers/measured_boot/measured_boot.h | 18 ------------- include/plat/common/platform.h | 12 ++++++++- plat/arm/board/fvp/fvp_bl2_setup.c | 3 --- plat/arm/board/fvp/fvp_measured_boot.c | 28 ++++++++++++++++++- 7 files changed, 46 insertions(+), 79 deletions(-) delete mode 100644 drivers/measured_boot/measured_boot.c delete mode 100644 include/drivers/measured_boot/measured_boot.h diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index 197c057e1..90fe39bc2 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -15,9 +15,6 @@ #include #include #include -#if MEASURED_BOOT -#include -#endif #include #include @@ -95,24 +92,19 @@ void bl2_main(void) #if TRUSTED_BOARD_BOOT /* Initialize authentication module */ auth_mod_init(); - -#if MEASURED_BOOT - /* Initialize measured boot module */ - measured_boot_init(); - -#endif /* MEASURED_BOOT */ #endif /* TRUSTED_BOARD_BOOT */ + /* Initialize the Measured Boot backend */ + bl2_plat_mboot_init(); + /* Initialize boot source */ bl2_plat_preload_setup(); /* Load the subsequent bootloader images. */ next_bl_ep_info = bl2_load_images(); -#if MEASURED_BOOT - /* Finalize measured boot */ - measured_boot_finish(); -#endif /* MEASURED_BOOT */ + /* Teardown the Measured Boot backend */ + bl2_plat_mboot_finish(); #if !BL2_AT_EL3 && !ENABLE_RME #ifndef __aarch64__ diff --git a/drivers/measured_boot/measured_boot.c b/drivers/measured_boot/measured_boot.c deleted file mode 100644 index 37fddfbdc..000000000 --- a/drivers/measured_boot/measured_boot.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -/* - * Init Measured Boot driver - * - * Initialises Event Log. - */ -void measured_boot_init(void) -{ - event_log_init(); -} - -/* - * Finish Measured Boot driver - * - * Finalises Event Log and dumps the records to the debug console. - */ -void measured_boot_finish(void) -{ - uint8_t *log_addr; - size_t log_size; - int rc; - - rc = event_log_finalise(&log_addr, &log_size); - if (rc != 0) { - panic(); - } - - dump_event_log(log_addr, log_size); -} diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk index 497fdbaae..e3399c067 100644 --- a/drivers/measured_boot/measured_boot.mk +++ b/drivers/measured_boot/measured_boot.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Arm Limited. All rights reserved. +# Copyright (c) 2020-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -45,8 +45,7 @@ endif MEASURED_BOOT_SRC_DIR := drivers/measured_boot/ -MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}measured_boot.c \ - ${MEASURED_BOOT_SRC_DIR}event_log.c \ - ${MEASURED_BOOT_SRC_DIR}event_print.c +MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}event_log.c \ + ${MEASURED_BOOT_SRC_DIR}event_print.c BL2_SOURCES += ${MEASURED_BOOT_SOURCES} diff --git a/include/drivers/measured_boot/measured_boot.h b/include/drivers/measured_boot/measured_boot.h deleted file mode 100644 index 05be4a941..000000000 --- a/include/drivers/measured_boot/measured_boot.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2020-2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef MEASURED_BOOT_H -#define MEASURED_BOOT_H - -#include - -#include - -/* Functions' declarations */ -void measured_boot_init(void); -void measured_boot_finish(void); - -#endif /* MEASURED_BOOT_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 434835ee7..5fc21a57d 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -210,7 +210,17 @@ int bl2_plat_handle_post_image_load(unsigned int image_id); #if MEASURED_BOOT /* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ void bl2_plat_get_hash(void *data); -#endif + +void bl2_plat_mboot_init(void); +void bl2_plat_mboot_finish(void); +#else +static inline void bl2_plat_mboot_init(void) +{ +} +static inline void bl2_plat_mboot_finish(void) +{ +} +#endif /* MEASURED_BOOT */ /******************************************************************************* * Mandatory BL2 at EL3 functions: Must be implemented if BL2_AT_EL3 image is diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index abf7988e7..634210bcc 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -9,9 +9,6 @@ #include #include #include -#if MEASURED_BOOT -#include -#endif #include #include diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index 5dcadba36..fae34b6a0 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2020, Arm Limited. All rights reserved. + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include + #include #include @@ -36,3 +38,27 @@ const measured_boot_data_t *plat_get_measured_boot_data(void) { return &fvp_measured_boot_data; } + +void bl2_plat_mboot_init(void) +{ + event_log_init(); +} + +void bl2_plat_mboot_finish(void) +{ + uint8_t *log_addr; + size_t log_size; + int rc; + + rc = event_log_finalise(&log_addr, &log_size); + if (rc != 0) { + /* + * It is a fatal error because on FVP secure world software + * assumes that a valid event log exists and will use it to + * record the measurements into the fTPM + */ + panic(); + } + + dump_event_log(log_addr, log_size); +} -- cgit v1.2.3 From d89bec83dca034eafc7b0405bb6812518276609f Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Wed, 7 Jul 2021 14:47:08 +0200 Subject: build(measured boot): rename measured boot makefile With the removal of the generic functions measured_boot_init()/finish(), measured_boot.mk becomes specific to the TCG event log backend. Change its file name to event_log.mk. Also, the Event Log driver is one of the backend of measured boot hence created a separate folder for it under the measured_boot directory. Alongside done some cosmetic changes (adding a comment and fixing identation). Change-Id: I4ce3300e6958728dc15ca5cced09eaa01510606c Signed-off-by: Sandrine Bailleux --- drivers/measured_boot/event_log.c | 359 --------------------- drivers/measured_boot/event_log/event_log.c | 359 +++++++++++++++++++++ drivers/measured_boot/event_log/event_log.mk | 52 +++ drivers/measured_boot/event_log/event_print.c | 265 +++++++++++++++ drivers/measured_boot/event_print.c | 265 --------------- drivers/measured_boot/measured_boot.mk | 51 --- include/drivers/measured_boot/event_log.h | 97 ------ .../drivers/measured_boot/event_log/event_log.h | 97 ++++++ include/drivers/measured_boot/event_log/tcg.h | 304 +++++++++++++++++ include/drivers/measured_boot/tcg.h | 304 ----------------- plat/arm/board/fvp/fvp_measured_boot.c | 2 +- plat/arm/common/arm_common.mk | 2 +- 12 files changed, 1079 insertions(+), 1078 deletions(-) delete mode 100644 drivers/measured_boot/event_log.c create mode 100644 drivers/measured_boot/event_log/event_log.c create mode 100644 drivers/measured_boot/event_log/event_log.mk create mode 100644 drivers/measured_boot/event_log/event_print.c delete mode 100644 drivers/measured_boot/event_print.c delete mode 100644 drivers/measured_boot/measured_boot.mk delete mode 100644 include/drivers/measured_boot/event_log.h create mode 100644 include/drivers/measured_boot/event_log/event_log.h create mode 100644 include/drivers/measured_boot/event_log/tcg.h delete mode 100644 include/drivers/measured_boot/tcg.h diff --git a/drivers/measured_boot/event_log.c b/drivers/measured_boot/event_log.c deleted file mode 100644 index 634ab7486..000000000 --- a/drivers/measured_boot/event_log.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 2020-2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -/* Event Log data */ -static uint8_t event_log[EVENT_LOG_SIZE]; - -/* End of Event Log */ -#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U) - -CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size); - -/* Pointer in event_log[] */ -static uint8_t *log_ptr = event_log; - -/* Pointer to measured_boot_data_t */ -const static measured_boot_data_t *plat_data_ptr; - -static uintptr_t tos_fw_config_base; -static uintptr_t nt_fw_config_base; - -/* TCG_EfiSpecIdEvent */ -static const id_event_headers_t id_event_header = { - .header = { - .pcr_index = PCR_0, - .event_type = EV_NO_ACTION, - .digest = {0}, - .event_size = (uint32_t)(sizeof(id_event_struct_t) + - (sizeof(id_event_algorithm_size_t) * - HASH_ALG_COUNT)) - }, - - .struct_header = { - .signature = TCG_ID_EVENT_SIGNATURE_03, - .platform_class = PLATFORM_CLASS_CLIENT, - .spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2, - .spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2, - .spec_errata = TCG_SPEC_ERRATA_TPM2, - .uintn_size = (uint8_t)(sizeof(unsigned int) / - sizeof(uint32_t)), - .number_of_algorithms = HASH_ALG_COUNT - } -}; - -static const event2_header_t locality_event_header = { - /* - * All EV_NO_ACTION events SHALL set - * TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified - */ - .pcr_index = PCR_0, - - /* - * All EV_NO_ACTION events SHALL set - * TCG_PCR_EVENT2.eventType = 03h - */ - .event_type = EV_NO_ACTION, - - /* - * All EV_NO_ACTION events SHALL set TCG_PCR_EVENT2.digests to all - * 0x00's for each allocated Hash algorithm - */ - .digests = { - .count = HASH_ALG_COUNT - } -}; - -/* - * Add TCG_PCR_EVENT2 event - * - * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes - * @param[in] image_ptr Pointer to image_data_t structure - * - * There must be room for storing this new event into the event log buffer. - */ -static void add_event2(const uint8_t *hash, const image_data_t *image_ptr) -{ - void *ptr = log_ptr; - uint32_t name_len; - - assert(image_ptr != NULL); - assert(image_ptr->name != NULL); - - name_len = (uint32_t)strlen(image_ptr->name) + 1U; - - /* Check for space in Event Log buffer */ - assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <= - EVENT_LOG_END); - - /* - * As per TCG specifications, firmware components that are measured - * into PCR[0] must be logged in the event log using the event type - * EV_POST_CODE. - */ - /* TCG_PCR_EVENT2.PCRIndex */ - ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr; - - /* TCG_PCR_EVENT2.EventType */ - ((event2_header_t *)ptr)->event_type = EV_POST_CODE; - - /* TCG_PCR_EVENT2.Digests.Count */ - ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests); - ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT; - - /* TCG_PCR_EVENT2.Digests[] */ - ptr = (uint8_t *)((uintptr_t)ptr + - offsetof(tpml_digest_values, digests)); - - /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ - ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; - - /* TCG_PCR_EVENT2.Digests[].Digest[] */ - ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); - - if (hash == NULL) { - /* Get BL2 hash from DTB */ - bl2_plat_get_hash(ptr); - } else { - /* Copy digest */ - (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); - } - - /* TCG_PCR_EVENT2.EventSize */ - ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE); - ((event2_data_t *)ptr)->event_size = name_len; - - /* Copy event data to TCG_PCR_EVENT2.Event */ - (void)memcpy((void *)(((event2_data_t *)ptr)->event), - (const void *)image_ptr->name, name_len); - - /* End of event data */ - log_ptr = (uint8_t *)((uintptr_t)ptr + - offsetof(event2_data_t, event) + name_len); -} - -/* - * Init Event Log - * - * Initialises Event Log by writing Specification ID and - * Startup Locality events. - */ -void event_log_init(void) -{ - const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE; - void *ptr = event_log; - - /* Get pointer to platform's measured_boot_data_t structure */ - plat_data_ptr = plat_get_measured_boot_data(); - - /* - * Add Specification ID Event first - * - * Copy TCG_EfiSpecIDEventStruct structure header - */ - (void)memcpy(ptr, (const void *)&id_event_header, - sizeof(id_event_header)); - ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header)); - - /* TCG_EfiSpecIdEventAlgorithmSize structure */ - ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID; - ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE; - ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t)); - - /* - * TCG_EfiSpecIDEventStruct.vendorInfoSize - * No vendor data - */ - ((id_event_struct_data_t *)ptr)->vendor_info_size = 0; - ptr = (uint8_t *)((uintptr_t)ptr + - offsetof(id_event_struct_data_t, vendor_info)); - - /* - * The Startup Locality event should be placed in the log before - * any event which extends PCR[0]. - * - * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 - */ - - /* Copy Startup Locality Event Header */ - (void)memcpy(ptr, (const void *)&locality_event_header, - sizeof(locality_event_header)); - ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header)); - - /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ - ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; - - /* TCG_PCR_EVENT2.Digests[].Digest[] */ - (void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID); - ptr = (uint8_t *)((uintptr_t)ptr + - offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE); - - /* TCG_PCR_EVENT2.EventSize */ - ((event2_data_t *)ptr)->event_size = - (uint32_t)sizeof(startup_locality_event_t); - ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); - - /* TCG_EfiStartupLocalityEvent.Signature */ - (void)memcpy(ptr, (const void *)locality_signature, - sizeof(TCG_STARTUP_LOCALITY_SIGNATURE)); - - /* - * TCG_EfiStartupLocalityEvent.StartupLocality = 0: - * the platform's boot firmware - */ - ((startup_locality_event_t *)ptr)->startup_locality = 0U; - ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); - - log_ptr = (uint8_t *)ptr; - - /* Add BL2 event */ - add_event2(NULL, plat_data_ptr->images_data); -} - -/* - * Calculate and write hash of image, configuration data, etc. - * to Event Log. - * - * @param[in] data_base Address of data - * @param[in] data_size Size of data - * @param[in] data_id Data ID - * @return: - * 0 = success - * < 0 = error - */ -int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, - uint32_t data_id) -{ - const image_data_t *data_ptr = plat_data_ptr->images_data; - unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; - int rc; - - /* Get the metadata associated with this image. */ - while ((data_ptr->id != INVALID_ID) && (data_ptr->id != data_id)) { - data_ptr++; - } - assert(data_ptr->id != INVALID_ID); - - if (data_id == TOS_FW_CONFIG_ID) { - tos_fw_config_base = data_base; - } else if (data_id == NT_FW_CONFIG_ID) { - nt_fw_config_base = data_base; - } else { - /* No action */ - } - - /* Calculate hash */ - rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID, - (void *)data_base, data_size, hash_data); - if (rc != 0) { - return rc; - } - - add_event2(hash_data, data_ptr); - return 0; -} - -/* - * Finalise Event Log - * - * @param[out] log_addr Pointer to return Event Log address - * @param[out] log_size Pointer to return Event Log size - * @return: - * 0 = success - * < 0 = error code - */ -int event_log_finalise(uint8_t **log_addr, size_t *log_size) -{ - /* Event Log size */ - size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log; - int rc; - - assert(log_addr != NULL); - assert(log_size != NULL); - - if (nt_fw_config_base == 0UL) { - ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT"); - return -ENOENT; - } - - /* - * Set Event Log data in NT_FW_CONFIG and - * get Event Log address in Non-Secure memory - */ - if (plat_data_ptr->set_nt_fw_info != NULL) { - - /* Event Log address in Non-Secure memory */ - uintptr_t ns_log_addr; - - rc = plat_data_ptr->set_nt_fw_info( - nt_fw_config_base, -#ifdef SPD_opteed - (uintptr_t)event_log, -#endif - num_bytes, &ns_log_addr); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "NT"); - return rc; - } - - /* Copy Event Log to Non-secure memory */ - (void)memcpy((void *)ns_log_addr, (const void *)event_log, - num_bytes); - - /* Ensure that the Event Log is visible in Non-secure memory */ - flush_dcache_range(ns_log_addr, num_bytes); - - /* Return Event Log address in Non-Secure memory */ - *log_addr = (uint8_t *)ns_log_addr; - - } else { - INFO("%s(): set_%s_fw_info not set\n", __func__, "nt"); - - /* Return Event Log address in Secure memory */ - *log_addr = event_log; - } - - if (tos_fw_config_base != 0UL) { - if (plat_data_ptr->set_tos_fw_info != NULL) { - - /* Set Event Log data in TOS_FW_CONFIG */ - rc = plat_data_ptr->set_tos_fw_info( - tos_fw_config_base, - (uintptr_t)event_log, - num_bytes); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "TOS"); - return rc; - } - } else { - INFO("%s(): set_%s_fw_info not set\n", __func__, "tos"); - } - } else { - INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS"); - } - - /* Ensure that the Event Log is visible in Secure memory */ - flush_dcache_range((uintptr_t)event_log, num_bytes); - - /* Return Event Log size */ - *log_size = num_bytes; - - return 0; -} diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c new file mode 100644 index 000000000..f713595db --- /dev/null +++ b/drivers/measured_boot/event_log/event_log.c @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/* Event Log data */ +static uint8_t event_log[EVENT_LOG_SIZE]; + +/* End of Event Log */ +#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U) + +CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size); + +/* Pointer in event_log[] */ +static uint8_t *log_ptr = event_log; + +/* Pointer to measured_boot_data_t */ +const static measured_boot_data_t *plat_data_ptr; + +static uintptr_t tos_fw_config_base; +static uintptr_t nt_fw_config_base; + +/* TCG_EfiSpecIdEvent */ +static const id_event_headers_t id_event_header = { + .header = { + .pcr_index = PCR_0, + .event_type = EV_NO_ACTION, + .digest = {0}, + .event_size = (uint32_t)(sizeof(id_event_struct_t) + + (sizeof(id_event_algorithm_size_t) * + HASH_ALG_COUNT)) + }, + + .struct_header = { + .signature = TCG_ID_EVENT_SIGNATURE_03, + .platform_class = PLATFORM_CLASS_CLIENT, + .spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2, + .spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2, + .spec_errata = TCG_SPEC_ERRATA_TPM2, + .uintn_size = (uint8_t)(sizeof(unsigned int) / + sizeof(uint32_t)), + .number_of_algorithms = HASH_ALG_COUNT + } +}; + +static const event2_header_t locality_event_header = { + /* + * All EV_NO_ACTION events SHALL set + * TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified + */ + .pcr_index = PCR_0, + + /* + * All EV_NO_ACTION events SHALL set + * TCG_PCR_EVENT2.eventType = 03h + */ + .event_type = EV_NO_ACTION, + + /* + * All EV_NO_ACTION events SHALL set TCG_PCR_EVENT2.digests to all + * 0x00's for each allocated Hash algorithm + */ + .digests = { + .count = HASH_ALG_COUNT + } +}; + +/* + * Add TCG_PCR_EVENT2 event + * + * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes + * @param[in] image_ptr Pointer to image_data_t structure + * + * There must be room for storing this new event into the event log buffer. + */ +static void add_event2(const uint8_t *hash, const image_data_t *image_ptr) +{ + void *ptr = log_ptr; + uint32_t name_len; + + assert(image_ptr != NULL); + assert(image_ptr->name != NULL); + + name_len = (uint32_t)strlen(image_ptr->name) + 1U; + + /* Check for space in Event Log buffer */ + assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <= + EVENT_LOG_END); + + /* + * As per TCG specifications, firmware components that are measured + * into PCR[0] must be logged in the event log using the event type + * EV_POST_CODE. + */ + /* TCG_PCR_EVENT2.PCRIndex */ + ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr; + + /* TCG_PCR_EVENT2.EventType */ + ((event2_header_t *)ptr)->event_type = EV_POST_CODE; + + /* TCG_PCR_EVENT2.Digests.Count */ + ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests); + ((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT; + + /* TCG_PCR_EVENT2.Digests[] */ + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(tpml_digest_values, digests)); + + /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ + ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; + + /* TCG_PCR_EVENT2.Digests[].Digest[] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); + + if (hash == NULL) { + /* Get BL2 hash from DTB */ + bl2_plat_get_hash(ptr); + } else { + /* Copy digest */ + (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); + } + + /* TCG_PCR_EVENT2.EventSize */ + ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE); + ((event2_data_t *)ptr)->event_size = name_len; + + /* Copy event data to TCG_PCR_EVENT2.Event */ + (void)memcpy((void *)(((event2_data_t *)ptr)->event), + (const void *)image_ptr->name, name_len); + + /* End of event data */ + log_ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(event2_data_t, event) + name_len); +} + +/* + * Init Event Log + * + * Initialises Event Log by writing Specification ID and + * Startup Locality events. + */ +void event_log_init(void) +{ + const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE; + void *ptr = event_log; + + /* Get pointer to platform's measured_boot_data_t structure */ + plat_data_ptr = plat_get_measured_boot_data(); + + /* + * Add Specification ID Event first + * + * Copy TCG_EfiSpecIDEventStruct structure header + */ + (void)memcpy(ptr, (const void *)&id_event_header, + sizeof(id_event_header)); + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_header)); + + /* TCG_EfiSpecIdEventAlgorithmSize structure */ + ((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID; + ((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE; + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(id_event_algorithm_size_t)); + + /* + * TCG_EfiSpecIDEventStruct.vendorInfoSize + * No vendor data + */ + ((id_event_struct_data_t *)ptr)->vendor_info_size = 0; + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(id_event_struct_data_t, vendor_info)); + + /* + * The Startup Locality event should be placed in the log before + * any event which extends PCR[0]. + * + * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 + */ + + /* Copy Startup Locality Event Header */ + (void)memcpy(ptr, (const void *)&locality_event_header, + sizeof(locality_event_header)); + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(locality_event_header)); + + /* TCG_PCR_EVENT2.Digests[].AlgorithmId */ + ((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; + + /* TCG_PCR_EVENT2.Digests[].Digest[] */ + (void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID); + ptr = (uint8_t *)((uintptr_t)ptr + + offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE); + + /* TCG_PCR_EVENT2.EventSize */ + ((event2_data_t *)ptr)->event_size = + (uint32_t)sizeof(startup_locality_event_t); + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); + + /* TCG_EfiStartupLocalityEvent.Signature */ + (void)memcpy(ptr, (const void *)locality_signature, + sizeof(TCG_STARTUP_LOCALITY_SIGNATURE)); + + /* + * TCG_EfiStartupLocalityEvent.StartupLocality = 0: + * the platform's boot firmware + */ + ((startup_locality_event_t *)ptr)->startup_locality = 0U; + ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); + + log_ptr = (uint8_t *)ptr; + + /* Add BL2 event */ + add_event2(NULL, plat_data_ptr->images_data); +} + +/* + * Calculate and write hash of image, configuration data, etc. + * to Event Log. + * + * @param[in] data_base Address of data + * @param[in] data_size Size of data + * @param[in] data_id Data ID + * @return: + * 0 = success + * < 0 = error + */ +int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id) +{ + const image_data_t *data_ptr = plat_data_ptr->images_data; + unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; + int rc; + + /* Get the metadata associated with this image. */ + while ((data_ptr->id != INVALID_ID) && (data_ptr->id != data_id)) { + data_ptr++; + } + assert(data_ptr->id != INVALID_ID); + + if (data_id == TOS_FW_CONFIG_ID) { + tos_fw_config_base = data_base; + } else if (data_id == NT_FW_CONFIG_ID) { + nt_fw_config_base = data_base; + } else { + /* No action */ + } + + /* Calculate hash */ + rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID, + (void *)data_base, data_size, hash_data); + if (rc != 0) { + return rc; + } + + add_event2(hash_data, data_ptr); + return 0; +} + +/* + * Finalise Event Log + * + * @param[out] log_addr Pointer to return Event Log address + * @param[out] log_size Pointer to return Event Log size + * @return: + * 0 = success + * < 0 = error code + */ +int event_log_finalise(uint8_t **log_addr, size_t *log_size) +{ + /* Event Log size */ + size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log; + int rc; + + assert(log_addr != NULL); + assert(log_size != NULL); + + if (nt_fw_config_base == 0UL) { + ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT"); + return -ENOENT; + } + + /* + * Set Event Log data in NT_FW_CONFIG and + * get Event Log address in Non-Secure memory + */ + if (plat_data_ptr->set_nt_fw_info != NULL) { + + /* Event Log address in Non-Secure memory */ + uintptr_t ns_log_addr; + + rc = plat_data_ptr->set_nt_fw_info( + nt_fw_config_base, +#ifdef SPD_opteed + (uintptr_t)event_log, +#endif + num_bytes, &ns_log_addr); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "NT"); + return rc; + } + + /* Copy Event Log to Non-secure memory */ + (void)memcpy((void *)ns_log_addr, (const void *)event_log, + num_bytes); + + /* Ensure that the Event Log is visible in Non-secure memory */ + flush_dcache_range(ns_log_addr, num_bytes); + + /* Return Event Log address in Non-Secure memory */ + *log_addr = (uint8_t *)ns_log_addr; + + } else { + INFO("%s(): set_%s_fw_info not set\n", __func__, "nt"); + + /* Return Event Log address in Secure memory */ + *log_addr = event_log; + } + + if (tos_fw_config_base != 0UL) { + if (plat_data_ptr->set_tos_fw_info != NULL) { + + /* Set Event Log data in TOS_FW_CONFIG */ + rc = plat_data_ptr->set_tos_fw_info( + tos_fw_config_base, + (uintptr_t)event_log, + num_bytes); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "TOS"); + return rc; + } + } else { + INFO("%s(): set_%s_fw_info not set\n", __func__, "tos"); + } + } else { + INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS"); + } + + /* Ensure that the Event Log is visible in Secure memory */ + flush_dcache_range((uintptr_t)event_log, num_bytes); + + /* Return Event Log size */ + *log_size = num_bytes; + + return 0; +} diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk new file mode 100644 index 000000000..34bde171e --- /dev/null +++ b/drivers/measured_boot/event_log/event_log.mk @@ -0,0 +1,52 @@ +# +# Copyright (c) 2020-2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# Default log level to dump the event log (LOG_LEVEL_INFO) +EVENT_LOG_LEVEL ?= 40 + +# TPM hash algorithm. +# SHA-256 (or stronger) is required for all devices that are TPM 2.0 compliant. +TPM_HASH_ALG := sha256 + +ifeq (${TPM_HASH_ALG}, sha512) + MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 + TPM_ALG_ID := TPM_ALG_SHA512 + TCG_DIGEST_SIZE := 64U +else ifeq (${TPM_HASH_ALG}, sha384) + MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 + TPM_ALG_ID := TPM_ALG_SHA384 + TCG_DIGEST_SIZE := 48U +else + MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 + TPM_ALG_ID := TPM_ALG_SHA256 + TCG_DIGEST_SIZE := 32U +endif + +# Event Log length in bytes +EVENT_LOG_SIZE := 1024 + +# Set definitions for mbed TLS library and Measured Boot driver +$(eval $(call add_defines,\ + $(sort \ + MBEDTLS_MD_ID \ + TPM_ALG_ID \ + TCG_DIGEST_SIZE \ + EVENT_LOG_SIZE \ + EVENT_LOG_LEVEL \ +))) + +ifeq (${HASH_ALG}, sha256) + ifneq (${TPM_HASH_ALG}, sha256) + $(eval $(call add_define,MBEDTLS_SHA512_C)) + endif +endif + +MEASURED_BOOT_SRC_DIR := drivers/measured_boot/event_log/ + +MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}event_log.c \ + ${MEASURED_BOOT_SRC_DIR}event_print.c + +BL2_SOURCES += ${MEASURED_BOOT_SOURCES} diff --git a/drivers/measured_boot/event_log/event_print.c b/drivers/measured_boot/event_log/event_print.c new file mode 100644 index 000000000..e2ba1744d --- /dev/null +++ b/drivers/measured_boot/event_log/event_print.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +#if LOG_LEVEL >= EVENT_LOG_LEVEL + +/* + * Print TCG_EfiSpecIDEventStruct + * + * @param[in/out] log_addr Pointer to Event Log + * @param[in/out] log_size Pointer to Event Log size + */ +static void id_event_print(uint8_t **log_addr, size_t *log_size) +{ + unsigned int i; + uint8_t info_size, *info_size_ptr; + void *ptr = *log_addr; + id_event_headers_t *event = (id_event_headers_t *)ptr; + id_event_algorithm_size_t *alg_ptr; + uint32_t event_size, number_of_algorithms; + size_t digest_len; +#if ENABLE_ASSERTIONS + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); + bool valid = true; +#endif + + assert(*log_size >= sizeof(id_event_headers_t)); + + /* The fields of the event log header are defined to be PCRIndex of 0, + * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and + * Event content defined as TCG_EfiSpecIDEventStruct. + */ + LOG_EVENT("TCG_EfiSpecIDEvent:\n"); + LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index); + assert(event->header.pcr_index == (uint32_t)PCR_0); + + LOG_EVENT(" EventType : %u\n", event->header.event_type); + assert(event->header.event_type == EV_NO_ACTION); + + LOG_EVENT(" Digest :"); + for (i = 0U; i < sizeof(event->header.digest); ++i) { + uint8_t val = event->header.digest[i]; + + (void)printf(" %02x", val); + if ((i & U(0xF)) == 0U) { + (void)printf("\n"); + LOG_EVENT("\t\t :"); + } +#if ENABLE_ASSERTIONS + if (val != 0U) { + valid = false; + } +#endif + } + if ((i & U(0xF)) != 0U) { + (void)printf("\n"); + } + + assert(valid); + + /* EventSize */ + event_size = event->header.event_size; + LOG_EVENT(" EventSize : %u\n", event_size); + + LOG_EVENT(" Signature : %s\n", + event->struct_header.signature); + LOG_EVENT(" PlatformClass : %u\n", + event->struct_header.platform_class); + LOG_EVENT(" SpecVersion : %u.%u.%u\n", + event->struct_header.spec_version_major, + event->struct_header.spec_version_minor, + event->struct_header.spec_errata); + LOG_EVENT(" UintnSize : %u\n", + event->struct_header.uintn_size); + + /* NumberOfAlgorithms */ + number_of_algorithms = event->struct_header.number_of_algorithms; + LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms); + + /* Address of DigestSizes[] */ + alg_ptr = event->struct_header.digest_size; + + /* Size of DigestSizes[] */ + digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); + assert(((uintptr_t)alg_ptr + digest_len) <= (uintptr_t)end_ptr); + + LOG_EVENT(" DigestSizes :\n"); + for (i = 0U; i < number_of_algorithms; ++i) { + LOG_EVENT(" #%u AlgorithmId : SHA", i); + uint16_t algorithm_id = alg_ptr[i].algorithm_id; + + switch (algorithm_id) { + case TPM_ALG_SHA256: + (void)printf("256\n"); + break; + case TPM_ALG_SHA384: + (void)printf("384\n"); + break; + case TPM_ALG_SHA512: + (void)printf("512\n"); + break; + default: + (void)printf("?\n"); + ERROR("Algorithm 0x%x not found\n", algorithm_id); + assert(false); + } + + LOG_EVENT(" DigestSize : %u\n", + alg_ptr[i].digest_size); + } + + /* Address of VendorInfoSize */ + info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len); + assert((uintptr_t)info_size_ptr <= (uintptr_t)end_ptr); + + info_size = *info_size_ptr++; + LOG_EVENT(" VendorInfoSize : %u\n", info_size); + + /* Check VendorInfo end address */ + assert(((uintptr_t)info_size_ptr + info_size) <= (uintptr_t)end_ptr); + + /* Check EventSize */ + assert(event_size == (sizeof(id_event_struct_t) + + digest_len + info_size)); + if (info_size != 0U) { + LOG_EVENT(" VendorInfo :"); + for (i = 0U; i < info_size; ++i) { + (void)printf(" %02x", *info_size_ptr++); + } + (void)printf("\n"); + } + + *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr; + *log_addr = info_size_ptr; +} + +/* + * Print TCG_PCR_EVENT2 + * + * @param[in/out] log_addr Pointer to Event Log + * @param[in/out] log_size Pointer to Event Log size + */ +static void event2_print(uint8_t **log_addr, size_t *log_size) +{ + uint32_t event_size, count; + size_t sha_size, digests_size = 0U; + void *ptr = *log_addr; +#if ENABLE_ASSERTIONS + const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); +#endif + + assert(*log_size >= sizeof(event2_header_t)); + + LOG_EVENT("PCR_Event2:\n"); + LOG_EVENT(" PCRIndex : %u\n", + ((event2_header_t *)ptr)->pcr_index); + LOG_EVENT(" EventType : %u\n", + ((event2_header_t *)ptr)->event_type); + + count = ((event2_header_t *)ptr)->digests.count; + LOG_EVENT(" Digests Count : %u\n", count); + + /* Address of TCG_PCR_EVENT2.Digests[] */ + ptr = (uint8_t *)ptr + sizeof(event2_header_t); + assert(((uintptr_t)ptr <= (uintptr_t)end_ptr) && (count != 0U)); + + for (unsigned int i = 0U; i < count; ++i) { + /* Check AlgorithmId address */ + assert(((uintptr_t)ptr + + offsetof(tpmt_ha, digest)) <= (uintptr_t)end_ptr); + + LOG_EVENT(" #%u AlgorithmId : SHA", i); + switch (((tpmt_ha *)ptr)->algorithm_id) { + case TPM_ALG_SHA256: + sha_size = SHA256_DIGEST_SIZE; + (void)printf("256\n"); + break; + case TPM_ALG_SHA384: + sha_size = SHA384_DIGEST_SIZE; + (void)printf("384\n"); + break; + case TPM_ALG_SHA512: + sha_size = SHA512_DIGEST_SIZE; + (void)printf("512\n"); + break; + default: + (void)printf("?\n"); + ERROR("Algorithm 0x%x not found\n", + ((tpmt_ha *)ptr)->algorithm_id); + panic(); + } + + /* End of Digest[] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); + assert(((uintptr_t)ptr + sha_size) <= (uintptr_t)end_ptr); + + /* Total size of all digests */ + digests_size += sha_size; + + LOG_EVENT(" Digest :"); + for (unsigned int j = 0U; j < sha_size; ++j) { + (void)printf(" %02x", *(uint8_t *)ptr++); + if ((j & U(0xF)) == U(0xF)) { + (void)printf("\n"); + if (j < (sha_size - 1U)) { + LOG_EVENT("\t\t :"); + } + } + } + } + + /* TCG_PCR_EVENT2.EventSize */ + assert(((uintptr_t)ptr + offsetof(event2_data_t, event)) <= (uintptr_t)end_ptr); + + event_size = ((event2_data_t *)ptr)->event_size; + LOG_EVENT(" EventSize : %u\n", event_size); + + /* Address of TCG_PCR_EVENT2.Event[EventSize] */ + ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); + + /* End of TCG_PCR_EVENT2.Event[EventSize] */ + assert(((uintptr_t)ptr + event_size) <= (uintptr_t)end_ptr); + + if ((event_size == sizeof(startup_locality_event_t)) && + (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) { + LOG_EVENT(" Signature : %s\n", + ((startup_locality_event_t *)ptr)->signature); + LOG_EVENT(" StartupLocality : %u\n", + ((startup_locality_event_t *)ptr)->startup_locality); + } else { + LOG_EVENT(" Event : %s\n", (uint8_t *)ptr); + } + + *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr; + *log_addr = (uint8_t *)ptr + event_size; +} +#endif /* LOG_LEVEL >= EVENT_LOG_LEVEL */ + +/* + * Print Event Log + * + * @param[in] log_addr Pointer to Event Log + * @param[in] log_size Event Log size + */ +void dump_event_log(uint8_t *log_addr, size_t log_size) +{ +#if LOG_LEVEL >= EVENT_LOG_LEVEL + assert(log_addr != NULL); + + /* Print TCG_EfiSpecIDEvent */ + id_event_print(&log_addr, &log_size); + + while (log_size != 0U) { + event2_print(&log_addr, &log_size); + } +#endif +} diff --git a/drivers/measured_boot/event_print.c b/drivers/measured_boot/event_print.c deleted file mode 100644 index 84ed4b1cb..000000000 --- a/drivers/measured_boot/event_print.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include -#include - -#if LOG_LEVEL >= EVENT_LOG_LEVEL - -/* - * Print TCG_EfiSpecIDEventStruct - * - * @param[in/out] log_addr Pointer to Event Log - * @param[in/out] log_size Pointer to Event Log size - */ -static void id_event_print(uint8_t **log_addr, size_t *log_size) -{ - unsigned int i; - uint8_t info_size, *info_size_ptr; - void *ptr = *log_addr; - id_event_headers_t *event = (id_event_headers_t *)ptr; - id_event_algorithm_size_t *alg_ptr; - uint32_t event_size, number_of_algorithms; - size_t digest_len; -#if ENABLE_ASSERTIONS - const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); - bool valid = true; -#endif - - assert(*log_size >= sizeof(id_event_headers_t)); - - /* The fields of the event log header are defined to be PCRIndex of 0, - * EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and - * Event content defined as TCG_EfiSpecIDEventStruct. - */ - LOG_EVENT("TCG_EfiSpecIDEvent:\n"); - LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index); - assert(event->header.pcr_index == (uint32_t)PCR_0); - - LOG_EVENT(" EventType : %u\n", event->header.event_type); - assert(event->header.event_type == EV_NO_ACTION); - - LOG_EVENT(" Digest :"); - for (i = 0U; i < sizeof(event->header.digest); ++i) { - uint8_t val = event->header.digest[i]; - - (void)printf(" %02x", val); - if ((i & U(0xF)) == 0U) { - (void)printf("\n"); - LOG_EVENT("\t\t :"); - } -#if ENABLE_ASSERTIONS - if (val != 0U) { - valid = false; - } -#endif - } - if ((i & U(0xF)) != 0U) { - (void)printf("\n"); - } - - assert(valid); - - /* EventSize */ - event_size = event->header.event_size; - LOG_EVENT(" EventSize : %u\n", event_size); - - LOG_EVENT(" Signature : %s\n", - event->struct_header.signature); - LOG_EVENT(" PlatformClass : %u\n", - event->struct_header.platform_class); - LOG_EVENT(" SpecVersion : %u.%u.%u\n", - event->struct_header.spec_version_major, - event->struct_header.spec_version_minor, - event->struct_header.spec_errata); - LOG_EVENT(" UintnSize : %u\n", - event->struct_header.uintn_size); - - /* NumberOfAlgorithms */ - number_of_algorithms = event->struct_header.number_of_algorithms; - LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms); - - /* Address of DigestSizes[] */ - alg_ptr = event->struct_header.digest_size; - - /* Size of DigestSizes[] */ - digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); - assert(((uintptr_t)alg_ptr + digest_len) <= (uintptr_t)end_ptr); - - LOG_EVENT(" DigestSizes :\n"); - for (i = 0U; i < number_of_algorithms; ++i) { - LOG_EVENT(" #%u AlgorithmId : SHA", i); - uint16_t algorithm_id = alg_ptr[i].algorithm_id; - - switch (algorithm_id) { - case TPM_ALG_SHA256: - (void)printf("256\n"); - break; - case TPM_ALG_SHA384: - (void)printf("384\n"); - break; - case TPM_ALG_SHA512: - (void)printf("512\n"); - break; - default: - (void)printf("?\n"); - ERROR("Algorithm 0x%x not found\n", algorithm_id); - assert(false); - } - - LOG_EVENT(" DigestSize : %u\n", - alg_ptr[i].digest_size); - } - - /* Address of VendorInfoSize */ - info_size_ptr = (uint8_t *)((uintptr_t)alg_ptr + digest_len); - assert((uintptr_t)info_size_ptr <= (uintptr_t)end_ptr); - - info_size = *info_size_ptr++; - LOG_EVENT(" VendorInfoSize : %u\n", info_size); - - /* Check VendorInfo end address */ - assert(((uintptr_t)info_size_ptr + info_size) <= (uintptr_t)end_ptr); - - /* Check EventSize */ - assert(event_size == (sizeof(id_event_struct_t) + - digest_len + info_size)); - if (info_size != 0U) { - LOG_EVENT(" VendorInfo :"); - for (i = 0U; i < info_size; ++i) { - (void)printf(" %02x", *info_size_ptr++); - } - (void)printf("\n"); - } - - *log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr; - *log_addr = info_size_ptr; -} - -/* - * Print TCG_PCR_EVENT2 - * - * @param[in/out] log_addr Pointer to Event Log - * @param[in/out] log_size Pointer to Event Log size - */ -static void event2_print(uint8_t **log_addr, size_t *log_size) -{ - uint32_t event_size, count; - size_t sha_size, digests_size = 0U; - void *ptr = *log_addr; -#if ENABLE_ASSERTIONS - const uint8_t *end_ptr = (uint8_t *)((uintptr_t)*log_addr + *log_size); -#endif - - assert(*log_size >= sizeof(event2_header_t)); - - LOG_EVENT("PCR_Event2:\n"); - LOG_EVENT(" PCRIndex : %u\n", - ((event2_header_t *)ptr)->pcr_index); - LOG_EVENT(" EventType : %u\n", - ((event2_header_t *)ptr)->event_type); - - count = ((event2_header_t *)ptr)->digests.count; - LOG_EVENT(" Digests Count : %u\n", count); - - /* Address of TCG_PCR_EVENT2.Digests[] */ - ptr = (uint8_t *)ptr + sizeof(event2_header_t); - assert(((uintptr_t)ptr <= (uintptr_t)end_ptr) && (count != 0U)); - - for (unsigned int i = 0U; i < count; ++i) { - /* Check AlgorithmId address */ - assert(((uintptr_t)ptr + - offsetof(tpmt_ha, digest)) <= (uintptr_t)end_ptr); - - LOG_EVENT(" #%u AlgorithmId : SHA", i); - switch (((tpmt_ha *)ptr)->algorithm_id) { - case TPM_ALG_SHA256: - sha_size = SHA256_DIGEST_SIZE; - (void)printf("256\n"); - break; - case TPM_ALG_SHA384: - sha_size = SHA384_DIGEST_SIZE; - (void)printf("384\n"); - break; - case TPM_ALG_SHA512: - sha_size = SHA512_DIGEST_SIZE; - (void)printf("512\n"); - break; - default: - (void)printf("?\n"); - ERROR("Algorithm 0x%x not found\n", - ((tpmt_ha *)ptr)->algorithm_id); - panic(); - } - - /* End of Digest[] */ - ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); - assert(((uintptr_t)ptr + sha_size) <= (uintptr_t)end_ptr); - - /* Total size of all digests */ - digests_size += sha_size; - - LOG_EVENT(" Digest :"); - for (unsigned int j = 0U; j < sha_size; ++j) { - (void)printf(" %02x", *(uint8_t *)ptr++); - if ((j & U(0xF)) == U(0xF)) { - (void)printf("\n"); - if (j < (sha_size - 1U)) { - LOG_EVENT("\t\t :"); - } - } - } - } - - /* TCG_PCR_EVENT2.EventSize */ - assert(((uintptr_t)ptr + offsetof(event2_data_t, event)) <= (uintptr_t)end_ptr); - - event_size = ((event2_data_t *)ptr)->event_size; - LOG_EVENT(" EventSize : %u\n", event_size); - - /* Address of TCG_PCR_EVENT2.Event[EventSize] */ - ptr = (uint8_t *)((uintptr_t)ptr + offsetof(event2_data_t, event)); - - /* End of TCG_PCR_EVENT2.Event[EventSize] */ - assert(((uintptr_t)ptr + event_size) <= (uintptr_t)end_ptr); - - if ((event_size == sizeof(startup_locality_event_t)) && - (strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) { - LOG_EVENT(" Signature : %s\n", - ((startup_locality_event_t *)ptr)->signature); - LOG_EVENT(" StartupLocality : %u\n", - ((startup_locality_event_t *)ptr)->startup_locality); - } else { - LOG_EVENT(" Event : %s\n", (uint8_t *)ptr); - } - - *log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr; - *log_addr = (uint8_t *)ptr + event_size; -} -#endif /* LOG_LEVEL >= EVENT_LOG_LEVEL */ - -/* - * Print Event Log - * - * @param[in] log_addr Pointer to Event Log - * @param[in] log_size Event Log size - */ -void dump_event_log(uint8_t *log_addr, size_t log_size) -{ -#if LOG_LEVEL >= EVENT_LOG_LEVEL - assert(log_addr != NULL); - - /* Print TCG_EfiSpecIDEvent */ - id_event_print(&log_addr, &log_size); - - while (log_size != 0U) { - event2_print(&log_addr, &log_size); - } -#endif -} diff --git a/drivers/measured_boot/measured_boot.mk b/drivers/measured_boot/measured_boot.mk deleted file mode 100644 index e3399c067..000000000 --- a/drivers/measured_boot/measured_boot.mk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2020-2021, Arm Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -# Default log level to dump the event log (LOG_LEVEL_INFO) -EVENT_LOG_LEVEL ?= 40 - -# TPM hash algorithm -TPM_HASH_ALG := sha256 - -ifeq (${TPM_HASH_ALG}, sha512) - MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 - TPM_ALG_ID := TPM_ALG_SHA512 - TCG_DIGEST_SIZE := 64U -else ifeq (${TPM_HASH_ALG}, sha384) - MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 - TPM_ALG_ID := TPM_ALG_SHA384 - TCG_DIGEST_SIZE := 48U -else - MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 - TPM_ALG_ID := TPM_ALG_SHA256 - TCG_DIGEST_SIZE := 32U -endif - -# Event Log length in bytes -EVENT_LOG_SIZE := 1024 - -# Set definitions for mbed TLS library and Measured Boot driver -$(eval $(call add_defines,\ - $(sort \ - MBEDTLS_MD_ID \ - TPM_ALG_ID \ - TCG_DIGEST_SIZE \ - EVENT_LOG_SIZE \ - EVENT_LOG_LEVEL \ -))) - -ifeq (${HASH_ALG}, sha256) -ifneq (${TPM_HASH_ALG}, sha256) -$(eval $(call add_define,MBEDTLS_SHA512_C)) -endif -endif - -MEASURED_BOOT_SRC_DIR := drivers/measured_boot/ - -MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}event_log.c \ - ${MEASURED_BOOT_SRC_DIR}event_print.c - -BL2_SOURCES += ${MEASURED_BOOT_SOURCES} diff --git a/include/drivers/measured_boot/event_log.h b/include/drivers/measured_boot/event_log.h deleted file mode 100644 index b0ce6a762..000000000 --- a/include/drivers/measured_boot/event_log.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2020-2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef EVENT_LOG_H -#define EVENT_LOG_H - -#include - -#include -#include - -/* - * Set Event Log debug level to one of: - * - * LOG_LEVEL_ERROR - * LOG_LEVEL_INFO - * LOG_LEVEL_WARNING - * LOG_LEVEL_VERBOSE - */ -#if EVENT_LOG_LEVEL == LOG_LEVEL_ERROR -#define LOG_EVENT ERROR -#elif EVENT_LOG_LEVEL == LOG_LEVEL_NOTICE -#define LOG_EVENT NOTICE -#elif EVENT_LOG_LEVEL == LOG_LEVEL_WARNING -#define LOG_EVENT WARN -#elif EVENT_LOG_LEVEL == LOG_LEVEL_INFO -#define LOG_EVENT INFO -#elif EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE -#define LOG_EVENT VERBOSE -#else -#error "Not supported EVENT_LOG_LEVEL" -#endif - -/* Number of hashing algorithms supported */ -#define HASH_ALG_COUNT 1U - -#define INVALID_ID MAX_NUMBER_IDS - -#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) - -#define BL2_STRING "BL_2" -#define BL31_STRING "BL_31" -#define BL32_STRING "BL_32" -#define BL32_EXTRA1_IMAGE_STRING "BL32_EXTRA1_IMAGE" -#define BL32_EXTRA2_IMAGE_STRING "BL32_EXTRA2_IMAGE" -#define BL33_STRING "BL_33" -#define GPT_IMAGE_STRING "GPT" -#define HW_CONFIG_STRING "HW_CONFIG" -#define NT_FW_CONFIG_STRING "NT_FW_CONFIG" -#define SCP_BL2_IMAGE_STRING "SCP_BL2_IMAGE" -#define SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" -#define STM32_IMAGE_STRING "STM32" -#define TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" - -typedef struct { - unsigned int id; - const char *name; - unsigned int pcr; -} image_data_t; - -typedef struct { - const image_data_t *images_data; - int (*set_nt_fw_info)(uintptr_t config_base, -#ifdef SPD_opteed - uintptr_t log_addr, -#endif - size_t log_size, uintptr_t *ns_log_addr); - int (*set_tos_fw_info)(uintptr_t config_base, uintptr_t log_addr, - size_t log_size); -} measured_boot_data_t; - -#define ID_EVENT_SIZE (sizeof(id_event_headers_t) + \ - (sizeof(id_event_algorithm_size_t) * HASH_ALG_COUNT) + \ - sizeof(id_event_struct_data_t)) - -#define LOC_EVENT_SIZE (sizeof(event2_header_t) + \ - sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ - sizeof(event2_data_t) + \ - sizeof(startup_locality_event_t)) - -#define LOG_MIN_SIZE (ID_EVENT_SIZE + LOC_EVENT_SIZE) - -#define EVENT2_HDR_SIZE (sizeof(event2_header_t) + \ - sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ - sizeof(event2_data_t)) - -/* Functions' declarations */ -void event_log_init(void); -int event_log_finalise(uint8_t **log_addr, size_t *log_size); -void dump_event_log(uint8_t *log_addr, size_t log_size); -const measured_boot_data_t *plat_get_measured_boot_data(void); -int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, - uint32_t data_id); -#endif /* EVENT_LOG_H */ diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h new file mode 100644 index 000000000..353022437 --- /dev/null +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020-2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef EVENT_LOG_H +#define EVENT_LOG_H + +#include + +#include +#include + +/* + * Set Event Log debug level to one of: + * + * LOG_LEVEL_ERROR + * LOG_LEVEL_INFO + * LOG_LEVEL_WARNING + * LOG_LEVEL_VERBOSE + */ +#if EVENT_LOG_LEVEL == LOG_LEVEL_ERROR +#define LOG_EVENT ERROR +#elif EVENT_LOG_LEVEL == LOG_LEVEL_NOTICE +#define LOG_EVENT NOTICE +#elif EVENT_LOG_LEVEL == LOG_LEVEL_WARNING +#define LOG_EVENT WARN +#elif EVENT_LOG_LEVEL == LOG_LEVEL_INFO +#define LOG_EVENT INFO +#elif EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE +#define LOG_EVENT VERBOSE +#else +#error "Not supported EVENT_LOG_LEVEL" +#endif + +/* Number of hashing algorithms supported */ +#define HASH_ALG_COUNT 1U + +#define INVALID_ID MAX_NUMBER_IDS + +#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) + +#define BL2_STRING "BL_2" +#define BL31_STRING "BL_31" +#define BL32_STRING "BL_32" +#define BL32_EXTRA1_IMAGE_STRING "BL32_EXTRA1_IMAGE" +#define BL32_EXTRA2_IMAGE_STRING "BL32_EXTRA2_IMAGE" +#define BL33_STRING "BL_33" +#define GPT_IMAGE_STRING "GPT" +#define HW_CONFIG_STRING "HW_CONFIG" +#define NT_FW_CONFIG_STRING "NT_FW_CONFIG" +#define SCP_BL2_IMAGE_STRING "SCP_BL2_IMAGE" +#define SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" +#define STM32_IMAGE_STRING "STM32" +#define TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" + +typedef struct { + unsigned int id; + const char *name; + unsigned int pcr; +} image_data_t; + +typedef struct { + const image_data_t *images_data; + int (*set_nt_fw_info)(uintptr_t config_base, +#ifdef SPD_opteed + uintptr_t log_addr, +#endif + size_t log_size, uintptr_t *ns_log_addr); + int (*set_tos_fw_info)(uintptr_t config_base, uintptr_t log_addr, + size_t log_size); +} measured_boot_data_t; + +#define ID_EVENT_SIZE (sizeof(id_event_headers_t) + \ + (sizeof(id_event_algorithm_size_t) * HASH_ALG_COUNT) + \ + sizeof(id_event_struct_data_t)) + +#define LOC_EVENT_SIZE (sizeof(event2_header_t) + \ + sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ + sizeof(event2_data_t) + \ + sizeof(startup_locality_event_t)) + +#define LOG_MIN_SIZE (ID_EVENT_SIZE + LOC_EVENT_SIZE) + +#define EVENT2_HDR_SIZE (sizeof(event2_header_t) + \ + sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ + sizeof(event2_data_t)) + +/* Functions' declarations */ +void event_log_init(void); +int event_log_finalise(uint8_t **log_addr, size_t *log_size); +void dump_event_log(uint8_t *log_addr, size_t log_size); +const measured_boot_data_t *plat_get_measured_boot_data(void); +int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, + uint32_t data_id); +#endif /* EVENT_LOG_H */ diff --git a/include/drivers/measured_boot/event_log/tcg.h b/include/drivers/measured_boot/event_log/tcg.h new file mode 100644 index 000000000..ab27a0844 --- /dev/null +++ b/include/drivers/measured_boot/event_log/tcg.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TCG_H +#define TCG_H + +#include + +#define TCG_ID_EVENT_SIGNATURE_03 "Spec ID Event03" +#define TCG_STARTUP_LOCALITY_SIGNATURE "StartupLocality" + +#define TCG_SPEC_VERSION_MAJOR_TPM2 2 +#define TCG_SPEC_VERSION_MINOR_TPM2 0 +#define TCG_SPEC_ERRATA_TPM2 2 + +/* + * Event types + * Ref. Table 9 Events + * TCG PC Client Platform Firmware Profile Specification. + */ +#define EV_PREBOOT_CERT U(0x00000000) +#define EV_POST_CODE U(0x00000001) +#define EV_UNUSED U(0x00000002) +#define EV_NO_ACTION U(0x00000003) +#define EV_SEPARATOR U(0x00000004) +#define EV_ACTION U(0x00000005) +#define EV_EVENT_TAG U(0x00000006) +#define EV_S_CRTM_CONTENTS U(0x00000007) +#define EV_S_CRTM_VERSION U(0x00000008) +#define EV_CPU_MICROCODE U(0x00000009) +#define EV_PLATFORM_CONFIG_FLAGS U(0x0000000A) +#define EV_TABLE_OF_DEVICES U(0x0000000B) +#define EV_COMPACT_HASH U(0x0000000C) +#define EV_IPL U(0x0000000D) +#define EV_IPL_PARTITION_DATA U(0x0000000E) +#define EV_NONHOST_CODE U(0x0000000F) +#define EV_NONHOST_CONFIG U(0x00000010) +#define EV_NONHOST_INFO U(0x00000011) +#define EV_OMIT_BOOT_DEVICE_EVENTS U(0x00000012) +#define EV_EFI_EVENT_BASE U(0x80000000) +#define EV_EFI_VARIABLE_DRIVER_CONFIG U(0x80000001) +#define EV_EFI_VARIABLE_BOOT U(0x80000002) +#define EV_EFI_BOOT_SERVICES_APPLICATION U(0x80000003) +#define EV_EFI_BOOT_SERVICES_DRIVER U(0x80000004) +#define EV_EFI_RUNTIME_SERVICES_DRIVER U(0x80000005) +#define EV_EFI_GPT_EVENT U(0x80000006) +#define EV_EFI_ACTION U(0x80000007) +#define EV_EFI_PLATFORM_FIRMWARE_BLOB U(0x80000008) +#define EV_EFI_HANDOFF_TABLES U(0x80000009) +#define EV_EFI_HCRTM_EVENT U(0x80000010) +#define EV_EFI_VARIABLE_AUTHORITY U(0x800000E0) + +/* + * TPM_ALG_ID constants. + * Ref. Table 9 - Definition of (UINT16) TPM_ALG_ID Constants + * Trusted Platform Module Library. Part 2: Structures + */ +#define TPM_ALG_SHA256 0x000B +#define TPM_ALG_SHA384 0x000C +#define TPM_ALG_SHA512 0x000D + +/* TCG Platform Type */ +#define PLATFORM_CLASS_CLIENT 0 +#define PLATFORM_CLASS_SERVER 1 + +/* SHA digest sizes in bytes */ +#define SHA1_DIGEST_SIZE 20 +#define SHA256_DIGEST_SIZE 32 +#define SHA384_DIGEST_SIZE 48 +#define SHA512_DIGEST_SIZE 64 + +enum { + /* + * SRTM, BIOS, Host Platform Extensions, Embedded + * Option ROMs and PI Drivers + */ + PCR_0 = 0, + /* Host Platform Configuration */ + PCR_1, + /* UEFI driver and application Code */ + PCR_2, + /* UEFI driver and application Configuration and Data */ + PCR_3, + /* UEFI Boot Manager Code (usually the MBR) and Boot Attempts */ + PCR_4, + /* + * Boot Manager Code Configuration and Data (for use + * by the Boot Manager Code) and GPT/Partition Table + */ + PCR_5, + /* Host Platform Manufacturer Specific */ + PCR_6, + /* Secure Boot Policy */ + PCR_7, + /* 8-15: Defined for use by the Static OS */ + PCR_8, + /* Debug */ + PCR_16 = 16 +}; + +#pragma pack(push, 1) + +/* + * PCR Event Header + * TCG EFI Protocol Specification + * 5.3 Event Log Header + */ +typedef struct { + /* PCRIndex: + * The PCR Index to which this event is extended + */ + uint32_t pcr_index; + + /* EventType: + * SHALL be an EV_NO_ACTION event + */ + uint32_t event_type; + + /* SHALL be 20 Bytes of 0x00 */ + uint8_t digest[SHA1_DIGEST_SIZE]; + + /* The size of the event */ + uint32_t event_size; + + /* SHALL be a TCG_EfiSpecIdEvent */ + uint8_t event[]; /* [event_data_size] */ +} tcg_pcr_event_t; + +/* + * Log Header Entry Data + * Ref. Table 14 TCG_EfiSpecIdEventAlgorithmSize + * TCG PC Client Platform Firmware Profile 9.4.5.1 + */ +typedef struct { + /* Algorithm ID (hashAlg) of the Hash used by BIOS */ + uint16_t algorithm_id; + + /* The size of the digest produced by the implemented Hash algorithm */ + uint16_t digest_size; +} id_event_algorithm_size_t; + +/* + * TCG_EfiSpecIdEvent structure + * Ref. Table 15 TCG_EfiSpecIdEvent + * TCG PC Client Platform Firmware Profile 9.4.5.1 + */ +typedef struct { + /* + * The NUL-terminated ASCII string "Spec ID Event03". + * SHALL be set to {0x53, 0x70, 0x65, 0x63, 0x20, 0x49, 0x44, + * 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x33, 0x00}. + */ + uint8_t signature[16]; + + /* + * The value for the Platform Class. + * The enumeration is defined in the TCG ACPI Specification Client + * Common Header. + */ + uint32_t platform_class; + + /* + * The PC Client Platform Profile Specification minor version number + * this BIOS supports. + * Any BIOS supporting this version (2.0) MUST set this value to 0x00. + */ + uint8_t spec_version_minor; + + /* + * The PC Client Platform Profile Specification major version number + * this BIOS supports. + * Any BIOS supporting this version (2.0) MUST set this value to 0x02. + */ + uint8_t spec_version_major; + + /* + * The PC Client Platform Profile Specification errata version number + * this BIOS supports. + * Any BIOS supporting this version (2.0) MUST set this value to 0x02. + */ + uint8_t spec_errata; + + /* + * Specifies the size of the UINTN fields used in various data + * structures used in this specification. + * 0x01 indicates UINT32 and 0x02 indicates UINT64. + */ + uint8_t uintn_size; + + /* + * The number of Hash algorithms in the digestSizes field. + * This field MUST be set to a value of 0x01 or greater. + */ + uint32_t number_of_algorithms; + + /* + * Each TCG_EfiSpecIdEventAlgorithmSize SHALL contain an algorithmId + * and digestSize for each hash algorithm used in the TCG_PCR_EVENT2 + * structure, the first of which is a Hash algorithmID and the second + * is the size of the respective digest. + */ + id_event_algorithm_size_t digest_size[]; /* number_of_algorithms */ +} id_event_struct_header_t; + +typedef struct { + /* + * Size in bytes of the VendorInfo field. + * Maximum value MUST be FFh bytes. + */ + uint8_t vendor_info_size; + + /* + * Provided for use by Platform Firmware implementer. The value might + * be used, for example, to provide more detailed information about the + * specific BIOS such as BIOS revision numbers, etc. The values within + * this field are not standardized and are implementer-specific. + * Platform-specific or -unique information MUST NOT be provided in + * this field. + * + */ + uint8_t vendor_info[]; /* [vendorInfoSize] */ +} id_event_struct_data_t; + +typedef struct { + id_event_struct_header_t struct_header; + id_event_struct_data_t struct_data; +} id_event_struct_t; + +typedef struct { + tcg_pcr_event_t header; + id_event_struct_header_t struct_header; +} id_event_headers_t; + +/* TPMT_HA Structure */ +typedef struct { + /* Selector of the hash contained in the digest that implies + * the size of the digest + */ + uint16_t algorithm_id; /* AlgorithmId */ + + /* Digest, depends on AlgorithmId */ + uint8_t digest[]; /* Digest[] */ +} tpmt_ha; + +/* + * TPML_DIGEST_VALUES Structure + */ +typedef struct { + /* The number of digests in the list */ + uint32_t count; /* Count */ + + /* The list of tagged digests, as sent to the TPM as part of a + * TPM2_PCR_Extend or as received from a TPM2_PCR_Event command + */ + tpmt_ha digests[]; /* Digests[Count] */ +} tpml_digest_values; + +/* + * TCG_PCR_EVENT2 header + */ +typedef struct { + /* The PCR Index to which this event was extended */ + uint32_t pcr_index; /* PCRIndex */ + + /* Type of event */ + uint32_t event_type; /* EventType */ + + /* Digests: + * A counted list of tagged digests, which contain the digest of + * the event data (or external data) for all active PCR banks + */ + tpml_digest_values digests; /* Digests */ +} event2_header_t; + +typedef struct event2_data { + /* The size of the event data */ + uint32_t event_size; /* EventSize */ + + /* The data of the event */ + uint8_t event[]; /* Event[EventSize] */ +} event2_data_t; + +/* + * Startup Locality Event + * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 + */ +typedef struct { + /* + * The NUL-terminated ASCII string "StartupLocality" SHALL be + * set to {0x53 0x74 0x61 0x72 0x74 0x75 0x70 0x4C 0x6F 0x63 + * 0x61 0x6C 0x69 0x74 0x79 0x00} + */ + uint8_t signature[16]; + + /* The Locality Indicator which sent the TPM2_Startup command */ + uint8_t startup_locality; +} startup_locality_event_t; + +#pragma pack(pop) + +#endif /* TCG_H */ diff --git a/include/drivers/measured_boot/tcg.h b/include/drivers/measured_boot/tcg.h deleted file mode 100644 index ab27a0844..000000000 --- a/include/drivers/measured_boot/tcg.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2020, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef TCG_H -#define TCG_H - -#include - -#define TCG_ID_EVENT_SIGNATURE_03 "Spec ID Event03" -#define TCG_STARTUP_LOCALITY_SIGNATURE "StartupLocality" - -#define TCG_SPEC_VERSION_MAJOR_TPM2 2 -#define TCG_SPEC_VERSION_MINOR_TPM2 0 -#define TCG_SPEC_ERRATA_TPM2 2 - -/* - * Event types - * Ref. Table 9 Events - * TCG PC Client Platform Firmware Profile Specification. - */ -#define EV_PREBOOT_CERT U(0x00000000) -#define EV_POST_CODE U(0x00000001) -#define EV_UNUSED U(0x00000002) -#define EV_NO_ACTION U(0x00000003) -#define EV_SEPARATOR U(0x00000004) -#define EV_ACTION U(0x00000005) -#define EV_EVENT_TAG U(0x00000006) -#define EV_S_CRTM_CONTENTS U(0x00000007) -#define EV_S_CRTM_VERSION U(0x00000008) -#define EV_CPU_MICROCODE U(0x00000009) -#define EV_PLATFORM_CONFIG_FLAGS U(0x0000000A) -#define EV_TABLE_OF_DEVICES U(0x0000000B) -#define EV_COMPACT_HASH U(0x0000000C) -#define EV_IPL U(0x0000000D) -#define EV_IPL_PARTITION_DATA U(0x0000000E) -#define EV_NONHOST_CODE U(0x0000000F) -#define EV_NONHOST_CONFIG U(0x00000010) -#define EV_NONHOST_INFO U(0x00000011) -#define EV_OMIT_BOOT_DEVICE_EVENTS U(0x00000012) -#define EV_EFI_EVENT_BASE U(0x80000000) -#define EV_EFI_VARIABLE_DRIVER_CONFIG U(0x80000001) -#define EV_EFI_VARIABLE_BOOT U(0x80000002) -#define EV_EFI_BOOT_SERVICES_APPLICATION U(0x80000003) -#define EV_EFI_BOOT_SERVICES_DRIVER U(0x80000004) -#define EV_EFI_RUNTIME_SERVICES_DRIVER U(0x80000005) -#define EV_EFI_GPT_EVENT U(0x80000006) -#define EV_EFI_ACTION U(0x80000007) -#define EV_EFI_PLATFORM_FIRMWARE_BLOB U(0x80000008) -#define EV_EFI_HANDOFF_TABLES U(0x80000009) -#define EV_EFI_HCRTM_EVENT U(0x80000010) -#define EV_EFI_VARIABLE_AUTHORITY U(0x800000E0) - -/* - * TPM_ALG_ID constants. - * Ref. Table 9 - Definition of (UINT16) TPM_ALG_ID Constants - * Trusted Platform Module Library. Part 2: Structures - */ -#define TPM_ALG_SHA256 0x000B -#define TPM_ALG_SHA384 0x000C -#define TPM_ALG_SHA512 0x000D - -/* TCG Platform Type */ -#define PLATFORM_CLASS_CLIENT 0 -#define PLATFORM_CLASS_SERVER 1 - -/* SHA digest sizes in bytes */ -#define SHA1_DIGEST_SIZE 20 -#define SHA256_DIGEST_SIZE 32 -#define SHA384_DIGEST_SIZE 48 -#define SHA512_DIGEST_SIZE 64 - -enum { - /* - * SRTM, BIOS, Host Platform Extensions, Embedded - * Option ROMs and PI Drivers - */ - PCR_0 = 0, - /* Host Platform Configuration */ - PCR_1, - /* UEFI driver and application Code */ - PCR_2, - /* UEFI driver and application Configuration and Data */ - PCR_3, - /* UEFI Boot Manager Code (usually the MBR) and Boot Attempts */ - PCR_4, - /* - * Boot Manager Code Configuration and Data (for use - * by the Boot Manager Code) and GPT/Partition Table - */ - PCR_5, - /* Host Platform Manufacturer Specific */ - PCR_6, - /* Secure Boot Policy */ - PCR_7, - /* 8-15: Defined for use by the Static OS */ - PCR_8, - /* Debug */ - PCR_16 = 16 -}; - -#pragma pack(push, 1) - -/* - * PCR Event Header - * TCG EFI Protocol Specification - * 5.3 Event Log Header - */ -typedef struct { - /* PCRIndex: - * The PCR Index to which this event is extended - */ - uint32_t pcr_index; - - /* EventType: - * SHALL be an EV_NO_ACTION event - */ - uint32_t event_type; - - /* SHALL be 20 Bytes of 0x00 */ - uint8_t digest[SHA1_DIGEST_SIZE]; - - /* The size of the event */ - uint32_t event_size; - - /* SHALL be a TCG_EfiSpecIdEvent */ - uint8_t event[]; /* [event_data_size] */ -} tcg_pcr_event_t; - -/* - * Log Header Entry Data - * Ref. Table 14 TCG_EfiSpecIdEventAlgorithmSize - * TCG PC Client Platform Firmware Profile 9.4.5.1 - */ -typedef struct { - /* Algorithm ID (hashAlg) of the Hash used by BIOS */ - uint16_t algorithm_id; - - /* The size of the digest produced by the implemented Hash algorithm */ - uint16_t digest_size; -} id_event_algorithm_size_t; - -/* - * TCG_EfiSpecIdEvent structure - * Ref. Table 15 TCG_EfiSpecIdEvent - * TCG PC Client Platform Firmware Profile 9.4.5.1 - */ -typedef struct { - /* - * The NUL-terminated ASCII string "Spec ID Event03". - * SHALL be set to {0x53, 0x70, 0x65, 0x63, 0x20, 0x49, 0x44, - * 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x33, 0x00}. - */ - uint8_t signature[16]; - - /* - * The value for the Platform Class. - * The enumeration is defined in the TCG ACPI Specification Client - * Common Header. - */ - uint32_t platform_class; - - /* - * The PC Client Platform Profile Specification minor version number - * this BIOS supports. - * Any BIOS supporting this version (2.0) MUST set this value to 0x00. - */ - uint8_t spec_version_minor; - - /* - * The PC Client Platform Profile Specification major version number - * this BIOS supports. - * Any BIOS supporting this version (2.0) MUST set this value to 0x02. - */ - uint8_t spec_version_major; - - /* - * The PC Client Platform Profile Specification errata version number - * this BIOS supports. - * Any BIOS supporting this version (2.0) MUST set this value to 0x02. - */ - uint8_t spec_errata; - - /* - * Specifies the size of the UINTN fields used in various data - * structures used in this specification. - * 0x01 indicates UINT32 and 0x02 indicates UINT64. - */ - uint8_t uintn_size; - - /* - * The number of Hash algorithms in the digestSizes field. - * This field MUST be set to a value of 0x01 or greater. - */ - uint32_t number_of_algorithms; - - /* - * Each TCG_EfiSpecIdEventAlgorithmSize SHALL contain an algorithmId - * and digestSize for each hash algorithm used in the TCG_PCR_EVENT2 - * structure, the first of which is a Hash algorithmID and the second - * is the size of the respective digest. - */ - id_event_algorithm_size_t digest_size[]; /* number_of_algorithms */ -} id_event_struct_header_t; - -typedef struct { - /* - * Size in bytes of the VendorInfo field. - * Maximum value MUST be FFh bytes. - */ - uint8_t vendor_info_size; - - /* - * Provided for use by Platform Firmware implementer. The value might - * be used, for example, to provide more detailed information about the - * specific BIOS such as BIOS revision numbers, etc. The values within - * this field are not standardized and are implementer-specific. - * Platform-specific or -unique information MUST NOT be provided in - * this field. - * - */ - uint8_t vendor_info[]; /* [vendorInfoSize] */ -} id_event_struct_data_t; - -typedef struct { - id_event_struct_header_t struct_header; - id_event_struct_data_t struct_data; -} id_event_struct_t; - -typedef struct { - tcg_pcr_event_t header; - id_event_struct_header_t struct_header; -} id_event_headers_t; - -/* TPMT_HA Structure */ -typedef struct { - /* Selector of the hash contained in the digest that implies - * the size of the digest - */ - uint16_t algorithm_id; /* AlgorithmId */ - - /* Digest, depends on AlgorithmId */ - uint8_t digest[]; /* Digest[] */ -} tpmt_ha; - -/* - * TPML_DIGEST_VALUES Structure - */ -typedef struct { - /* The number of digests in the list */ - uint32_t count; /* Count */ - - /* The list of tagged digests, as sent to the TPM as part of a - * TPM2_PCR_Extend or as received from a TPM2_PCR_Event command - */ - tpmt_ha digests[]; /* Digests[Count] */ -} tpml_digest_values; - -/* - * TCG_PCR_EVENT2 header - */ -typedef struct { - /* The PCR Index to which this event was extended */ - uint32_t pcr_index; /* PCRIndex */ - - /* Type of event */ - uint32_t event_type; /* EventType */ - - /* Digests: - * A counted list of tagged digests, which contain the digest of - * the event data (or external data) for all active PCR banks - */ - tpml_digest_values digests; /* Digests */ -} event2_header_t; - -typedef struct event2_data { - /* The size of the event data */ - uint32_t event_size; /* EventSize */ - - /* The data of the event */ - uint8_t event[]; /* Event[EventSize] */ -} event2_data_t; - -/* - * Startup Locality Event - * Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 - */ -typedef struct { - /* - * The NUL-terminated ASCII string "StartupLocality" SHALL be - * set to {0x53 0x74 0x61 0x72 0x74 0x75 0x70 0x4C 0x6F 0x63 - * 0x61 0x6C 0x69 0x74 0x79 0x00} - */ - uint8_t signature[16]; - - /* The Locality Indicator which sent the TPM2_Startup command */ - uint8_t startup_locality; -} startup_locality_event_t; - -#pragma pack(pop) - -#endif /* TCG_H */ diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index fae34b6a0..3697c3fe9 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -6,7 +6,7 @@ #include -#include +#include #include /* FVP table with platform specific image IDs, names and PCRs */ diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index f82392c6d..a20e258a9 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -406,7 +406,7 @@ ifeq (${RECLAIM_INIT_CODE}, 1) endif ifeq (${MEASURED_BOOT},1) - MEASURED_BOOT_MK := drivers/measured_boot/measured_boot.mk + MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk $(info Including ${MEASURED_BOOT_MK}) include ${MEASURED_BOOT_MK} endif -- cgit v1.2.3 From 140d9cb3e7d25c856e6186bd4bc773b17e22f609 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 20 Sep 2021 09:06:02 +0100 Subject: refactor(measured boot): move image measurement to generic layer Right now, the assumption is that the platform post-load hook takes care of measuring the image that just got loaded. This is how it's implemented on FVP. This patch moves the measurement into the generic code instead. load_auth_image() now calls plat_mboot_measure_image(), which is a new platform interface introduced in this patch to measure an image. This is called just after authenticating the image. Implement plat_mboot_measure_image() for the Arm FVP platform. The code is copied straight from the post-load hook. As a result, the FVP specific implementation of arm_bl2_plat_handle_post_image_load() is no longer needed. We can go back to using the Arm generic implementation of it. Change-Id: I7b4b8d28941a865e10af9d0eadaf2e4850942090 Signed-off-by: Sandrine Bailleux Signed-off-by: Manish V Badarkhe --- common/bl_common.c | 27 +++++++++++++++++----- include/plat/common/platform.h | 5 ++++ plat/arm/board/fvp/fvp_bl2_setup.c | 42 ---------------------------------- plat/arm/board/fvp/fvp_measured_boot.c | 27 ++++++++++++++++++++++ 4 files changed, 53 insertions(+), 48 deletions(-) diff --git a/common/bl_common.c b/common/bl_common.c index a7e28168d..3c37bcfa2 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -202,12 +202,27 @@ static int load_auth_image_recursive(unsigned int image_id, return -EAUTH; } - /* - * Flush the image to main memory so that it can be executed later by - * any CPU, regardless of cache and MMU state. This is only needed for - * child images, not for the parents (certificates). - */ if (is_parent_image == 0) { +#if IMAGE_BL2 + /* + * Measure the image. + * We do not measure its parents because these only play a role + * in authentication, which is orthogonal to measured boot. + * + * TODO: Change this code if we change our minds about measuring + * certificates. + */ + rc = plat_mboot_measure_image(image_id); + if (rc != 0) { + return rc; + } +#endif + /* + * Flush the image to main memory so that it can be executed + * later by any CPU, regardless of cache and MMU state. This + * is only needed for child images, not for the parents + * (certificates). + */ flush_dcache_range(image_data->image_base, image_data->image_size); } diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 5fc21a57d..bbf8ee80c 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -213,6 +213,7 @@ void bl2_plat_get_hash(void *data); void bl2_plat_mboot_init(void); void bl2_plat_mboot_finish(void); +int plat_mboot_measure_image(unsigned int image_id); #else static inline void bl2_plat_mboot_init(void) { @@ -220,6 +221,10 @@ static inline void bl2_plat_mboot_init(void) static inline void bl2_plat_mboot_finish(void) { } +static inline int plat_mboot_measure_image(unsigned int image_id __unused) +{ + return 0; +} #endif /* MEASURED_BOOT */ /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 634210bcc..5a17a0dca 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -70,45 +70,3 @@ struct bl_params *plat_get_next_bl_params(void) return arm_bl_params; } -#if MEASURED_BOOT -static int fvp_bl2_plat_handle_post_image_load(unsigned int image_id) -{ - const bl_mem_params_node_t *bl_mem_params = - get_bl_mem_params_node(image_id); - - assert(bl_mem_params != NULL); - - image_info_t info = bl_mem_params->image_info; - int err; - - if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) { - /* Calculate image hash and record data in Event Log */ - err = event_log_measure_and_record(info.image_base, - info.image_size, image_id); - if (err != 0) { - ERROR("%s%s image id %u (%i)\n", - "BL2: Failed to ", "record", image_id, err); - return err; - } - } - - err = arm_bl2_handle_post_image_load(image_id); - if (err != 0) { - ERROR("%s%s image id %u (%i)\n", - "BL2: Failed to ", "handle", image_id, err); - } - - return err; -} - -int arm_bl2_plat_handle_post_image_load(unsigned int image_id) -{ - int err = fvp_bl2_plat_handle_post_image_load(image_id); - - if (err != 0) { - ERROR("%s() returns %i\n", __func__, err); - } - - return err; -} -#endif /* MEASURED_BOOT */ diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index 3697c3fe9..64d4a858a 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -4,9 +4,12 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include +#include #include + #include /* FVP table with platform specific image IDs, names and PCRs */ @@ -62,3 +65,27 @@ void bl2_plat_mboot_finish(void) dump_event_log(log_addr, log_size); } + +int plat_mboot_measure_image(unsigned int image_id) +{ + const bl_mem_params_node_t *bl_mem_params = + get_bl_mem_params_node(image_id); + + assert(bl_mem_params != NULL); + + image_info_t info = bl_mem_params->image_info; + int err; + + if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) { + /* Calculate image hash and record data in Event Log */ + err = event_log_measure_record(info.image_base, + info.image_size, image_id); + if (err != 0) { + ERROR("%s%s image id %u (%i)\n", + "BL2: Failed to ", "record", image_id, err); + return err; + } + } + + return 0; +} -- cgit v1.2.3 From 9b0b34447422173a30a3980191cdd23ead983e42 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 17 Jun 2021 15:44:40 +0200 Subject: refactor(measured boot): rename add_event2() To a layman in TCG linguo, add_event2() is not straight forward to understand. Rename the function into event_log_record(). Change-Id: I75d53a656425cd78a41ebf2c4c4e4e57687adc0d Signed-off-by: Sandrine Bailleux --- drivers/measured_boot/event_log/event_log.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c index f713595db..32b7c55af 100644 --- a/drivers/measured_boot/event_log/event_log.c +++ b/drivers/measured_boot/event_log/event_log.c @@ -80,14 +80,14 @@ static const event2_header_t locality_event_header = { }; /* - * Add TCG_PCR_EVENT2 event + * Record a measurement as a TCG_PCR_EVENT2 event * * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes * @param[in] image_ptr Pointer to image_data_t structure * * There must be room for storing this new event into the event log buffer. */ -static void add_event2(const uint8_t *hash, const image_data_t *image_ptr) +static void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) { void *ptr = log_ptr; uint32_t name_len; @@ -222,7 +222,7 @@ void event_log_init(void) log_ptr = (uint8_t *)ptr; /* Add BL2 event */ - add_event2(NULL, plat_data_ptr->images_data); + event_log_record(NULL, plat_data_ptr->images_data); } /* @@ -264,7 +264,8 @@ int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, return rc; } - add_event2(hash_data, data_ptr); + event_log_record(hash_data, data_ptr); + return 0; } -- cgit v1.2.3 From 8cd09cfc9172ee9aed88af41f3601cb619651495 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 17 Jun 2021 16:10:40 +0200 Subject: refactor(measured boot): move BL2 measurement to platform layer Right now, event_log_init() does 2 things: 1) It writes all the necessary TCG data structures in the event log buffer. 2) It writes the first measurement (BL2's). Step 2) introduces in the TCG event log driver an assumption on what is getting measured and in what order. Ideally, the driver should only be concerned about generic operations, such as initializing the event log or recording a measurement in it. As much as possible, we should design the driver such that it could be reused in another project that has a different measure boot flow. For these reasons, move step 2) up to the caller, plat_mboot_init() in this case. Make event_log_record() a public function for this purpose. This refactoring will also help when we make BL1 record BL2's measurement into the event log (instead of BL2). Both BL1 and BL2 will need to call the driver's init function but only BL1 will need recording BL2's measurement. We can handle this through different implementations of plat_mboot_init() for BL1 and BL2, leaving the TCG event log driver unchanged. Change-Id: I358e097c1eedb54f82b866548dfc6bcade83d519 Signed-off-by: Sandrine Bailleux --- drivers/measured_boot/event_log/event_log.c | 15 ++++----------- include/drivers/measured_boot/event_log/event_log.h | 2 ++ plat/arm/board/fvp/fvp_measured_boot.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c index 32b7c55af..ff771aa53 100644 --- a/drivers/measured_boot/event_log/event_log.c +++ b/drivers/measured_boot/event_log/event_log.c @@ -87,13 +87,14 @@ static const event2_header_t locality_event_header = { * * There must be room for storing this new event into the event log buffer. */ -static void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) +void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) { void *ptr = log_ptr; uint32_t name_len; assert(image_ptr != NULL); assert(image_ptr->name != NULL); + assert(hash != NULL); name_len = (uint32_t)strlen(image_ptr->name) + 1U; @@ -126,13 +127,8 @@ static void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) /* TCG_PCR_EVENT2.Digests[].Digest[] */ ptr = (uint8_t *)((uintptr_t)ptr + offsetof(tpmt_ha, digest)); - if (hash == NULL) { - /* Get BL2 hash from DTB */ - bl2_plat_get_hash(ptr); - } else { - /* Copy digest */ - (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); - } + /* Copy digest */ + (void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); /* TCG_PCR_EVENT2.EventSize */ ptr = (uint8_t *)((uintptr_t)ptr + TCG_DIGEST_SIZE); @@ -220,9 +216,6 @@ void event_log_init(void) ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); log_ptr = (uint8_t *)ptr; - - /* Add BL2 event */ - event_log_record(NULL, plat_data_ptr->images_data); } /* diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h index 353022437..96fdc2faa 100644 --- a/include/drivers/measured_boot/event_log/event_log.h +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -94,4 +94,6 @@ void dump_event_log(uint8_t *log_addr, size_t log_size); const measured_boot_data_t *plat_get_measured_boot_data(void); int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, uint32_t data_id); +void event_log_record(const uint8_t *hash, const image_data_t *image_ptr); + #endif /* EVENT_LOG_H */ diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index 64d4a858a..24885f502 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -11,6 +11,7 @@ #include #include +#include /* FVP table with platform specific image IDs, names and PCRs */ static const image_data_t fvp_images_data[] = { @@ -44,7 +45,16 @@ const measured_boot_data_t *plat_get_measured_boot_data(void) void bl2_plat_mboot_init(void) { + uint8_t bl2_hash[TCG_DIGEST_SIZE]; + event_log_init(); + + /* Get BL2 hash from DTB */ + /* TODO: Avoid the extra copy of the hash buffer */ + bl2_plat_get_hash(bl2_hash); + + /* Add BL2 event */ + event_log_record(bl2_hash, &fvp_images_data[0]); } void bl2_plat_mboot_finish(void) -- cgit v1.2.3 From eab78e9ba4e36da27941bac99d2de0d5228eca6c Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 10 Aug 2021 20:51:55 +0100 Subject: refactor(measured_boot): remove passing of BL2 hash via device tree Subsequent patches will provide a solution to do the BL2 hash measurement and recording in BL1 itself, hence in preparation to adopt that solution remove the logic of passing BL2 hash measurement to BL2 component via TB_FW config. Change-Id: Iff9b3d4c6a236a33b942898fcdf799cbab89b724 Signed-off-by: Manish V Badarkhe --- include/lib/fconf/fconf_tbbr_getter.h | 3 - include/plat/arm/common/arm_dyn_cfg_helpers.h | 6 +- include/plat/arm/common/plat_arm.h | 3 - include/plat/common/platform.h | 11 ---- lib/fconf/fconf_tbbr_getter.c | 17 +----- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 13 ----- plat/arm/board/fvp/fvp_bl1_setup.c | 57 ------------------- plat/arm/board/fvp/fvp_measured_boot.c | 9 --- plat/arm/common/arm_bl2_setup.c | 11 ---- plat/arm/common/arm_dyn_cfg.c | 79 +-------------------------- plat/arm/common/arm_dyn_cfg_helpers.c | 30 +--------- plat/common/plat_bl1_common.c | 14 +---- 12 files changed, 9 insertions(+), 244 deletions(-) diff --git a/include/lib/fconf/fconf_tbbr_getter.h b/include/lib/fconf/fconf_tbbr_getter.h index 6066af6df..db98b68b0 100644 --- a/include/lib/fconf/fconf_tbbr_getter.h +++ b/include/lib/fconf/fconf_tbbr_getter.h @@ -23,9 +23,6 @@ struct tbbr_dyn_config_t { uint32_t disable_auth; void *mbedtls_heap_addr; size_t mbedtls_heap_size; -#if MEASURED_BOOT - uint8_t bl2_hash_data[TCG_DIGEST_SIZE]; -#endif }; extern struct tbbr_dyn_config_t tbbr_dyn_config; diff --git a/include/plat/arm/common/arm_dyn_cfg_helpers.h b/include/plat/arm/common/arm_dyn_cfg_helpers.h index 34bf07c0d..ff00fe7be 100644 --- a/include/plat/arm/common/arm_dyn_cfg_helpers.h +++ b/include/plat/arm/common/arm_dyn_cfg_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,8 +14,4 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node); int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size); -#if MEASURED_BOOT -int arm_set_bl2_hash_info(void *dtb, void *data); -#endif - #endif /* ARM_DYN_CFG_HELPERS_H */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 1500ed379..57e6953ab 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -250,9 +250,6 @@ void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); #if MEASURED_BOOT -/* Measured boot related functions */ -void arm_bl1_set_bl2_hash(const image_desc_t *image_desc); -void arm_bl2_get_hash(void *data); int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, size_t log_size); int arm_set_nt_fw_info(uintptr_t config_base, diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index bbf8ee80c..c7c4dcb39 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -181,14 +181,6 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved); int bl1_plat_handle_pre_image_load(unsigned int image_id); int bl1_plat_handle_post_image_load(unsigned int image_id); -#if MEASURED_BOOT -/* - * Calculates and writes BL2 hash data to the platform's defined location. - * For ARM platforms the data are written to TB_FW_CONFIG DTB. - */ -void bl1_plat_set_bl2_hash(const image_desc_t *image_desc); -#endif - /******************************************************************************* * Mandatory BL2 functions ******************************************************************************/ @@ -208,9 +200,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id); * Optional BL2 functions (may be overridden) ******************************************************************************/ #if MEASURED_BOOT -/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ -void bl2_plat_get_hash(void *data); - void bl2_plat_mboot_init(void); void bl2_plat_mboot_finish(void); int plat_mboot_measure_image(unsigned int image_id); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index 9a20ced4e..6f043e645 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * Copyright (c) 2019-2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -71,26 +71,13 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) } tbbr_dyn_config.mbedtls_heap_size = val32; -#if MEASURED_BOOT - /* Retrieve BL2 hash data details from the DTB */ - err = fdtw_read_bytes(dtb, node, "bl2_hash_data", TCG_DIGEST_SIZE, - &tbbr_dyn_config.bl2_hash_data); - if (err < 0) { - ERROR("FCONF: Read %s failed for '%s'\n", - "bytes", "bl2_hash_data"); - return err; - } -#endif VERBOSE("%s%s%s %d\n", "FCONF: `tbbr.", "disable_auth", "` cell found with value =", tbbr_dyn_config.disable_auth); VERBOSE("%s%s%s %p\n", "FCONF: `tbbr.", "mbedtls_heap_addr", "` cell found with value =", tbbr_dyn_config.mbedtls_heap_addr); VERBOSE("%s%s%s %zu\n", "FCONF: `tbbr.", "mbedtls_heap_size", "` cell found with value =", tbbr_dyn_config.mbedtls_heap_size); -#if MEASURED_BOOT - VERBOSE("%s%s%s %p\n", "FCONF: `tbbr.", "bl2_hash_data", - "` array found at address =", tbbr_dyn_config.bl2_hash_data); -#endif + return 0; } diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index 08d3c32ea..9e5b59a71 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -26,19 +26,6 @@ */ mbedtls_heap_addr = <0x0 0x0>; mbedtls_heap_size = <0x0>; - -#if MEASURED_BOOT - /* BL2 image hash calculated by BL1 */ - bl2_hash_data = [ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#if BL2_HASH_SIZE > 32 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#if BL2_HASH_SIZE > 48 - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#endif /* > 48 */ -#endif /* > 32 */ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]; -#endif /* MEASURED_BOOT */ }; /* diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index 06ee037dc..59fc0f326 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -76,63 +76,6 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) wfi(); } -#if MEASURED_BOOT -/* - * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. - */ -void bl1_plat_set_bl2_hash(const image_desc_t *image_desc) -{ - arm_bl1_set_bl2_hash(image_desc); -} - -/* - * Implementation for bl1_plat_handle_post_image_load(). This function - * populates the default arguments to BL2. The BL2 memory layout structure - * is allocated and the calculated layout is populated in arg1 to BL2. - */ -int bl1_plat_handle_post_image_load(unsigned int image_id) -{ - meminfo_t *bl2_tzram_layout; - meminfo_t *bl1_tzram_layout; - image_desc_t *image_desc; - entry_point_info_t *ep_info; - - if (image_id != BL2_IMAGE_ID) { - return 0; - } - - /* Get the image descriptor */ - image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(image_desc != NULL); - - /* Calculate BL2 hash and set it in TB_FW_CONFIG */ - bl1_plat_set_bl2_hash(image_desc); - - /* Get the entry point info */ - ep_info = &image_desc->ep_info; - - /* Find out how much free trusted ram remains after BL1 load */ - bl1_tzram_layout = bl1_plat_sec_mem_layout(); - - /* - * Create a new layout of memory for BL2 as seen by BL1 i.e. - * tell it the amount of total and free memory available. - * This layout is created at the first free address visible - * to BL2. BL2 will read the memory layout before using its - * memory for other purposes. - */ - bl2_tzram_layout = (meminfo_t *)bl1_tzram_layout->total_base; - - bl1_calc_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout); - - ep_info->args.arg1 = (uintptr_t)bl2_tzram_layout; - - VERBOSE("BL1: BL2 memory layout address = %p\n", - (void *)bl2_tzram_layout); - return 0; -} -#endif /* MEASURED_BOOT */ - /******************************************************************************* * The following function checks if Firmware update is needed by checking error * reported in NV flag. diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index 24885f502..f0de7521e 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -45,16 +45,7 @@ const measured_boot_data_t *plat_get_measured_boot_data(void) void bl2_plat_mboot_init(void) { - uint8_t bl2_hash[TCG_DIGEST_SIZE]; - event_log_init(); - - /* Get BL2 hash from DTB */ - /* TODO: Avoid the extra copy of the hash buffer */ - bl2_plat_get_hash(bl2_hash); - - /* Add BL2 event */ - event_log_record(bl2_hash, &fvp_images_data[0]); } void bl2_plat_mboot_finish(void) diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 2871b1bf0..08c014d8e 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -48,9 +48,6 @@ CASSERT(BL2_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl2_base_overflows); #pragma weak bl2_platform_setup #pragma weak bl2_plat_arch_setup #pragma weak bl2_plat_sec_mem_layout -#if MEASURED_BOOT -#pragma weak bl2_plat_get_hash -#endif #if ENABLE_RME #define MAP_BL2_TOTAL MAP_REGION_FLAT( \ @@ -323,11 +320,3 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) { return arm_bl2_plat_handle_post_image_load(image_id); } - -#if MEASURED_BOOT -/* Read TCG_DIGEST_SIZE bytes of BL2 hash data */ -void bl2_plat_get_hash(void *data) -{ - arm_bl2_get_hash(data); -} -#endif diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 30473be31..6aae9ae59 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,10 +15,6 @@ #include #if TRUSTED_BOARD_BOOT #include -#if MEASURED_BOOT -#include -#include -#endif #endif #include #include @@ -115,82 +111,13 @@ void arm_bl1_set_mbedtls_heap(void) * images. It's critical because BL2 won't be able to proceed * without the heap info. * - * In MEASURED_BOOT case flushing is done in - * arm_bl1_set_bl2_hash() function which is called after heap - * information is written in the DTB. + * In MEASURED_BOOT case flushing is done in a function which + * is called after heap information is written in the DTB. */ flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize(dtb)); #endif /* !MEASURED_BOOT */ } } - -#if MEASURED_BOOT -/* - * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. - * Executed only from BL1. - */ -void arm_bl1_set_bl2_hash(const image_desc_t *image_desc) -{ - unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; - const image_info_t image_info = image_desc->image_info; - uintptr_t tb_fw_cfg_dtb; - int err; - const struct dyn_cfg_dtb_info_t *tb_fw_config_info; - - tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); - assert(tb_fw_config_info != NULL); - - tb_fw_cfg_dtb = tb_fw_config_info->config_addr; - - /* - * If tb_fw_cfg_dtb==NULL then DTB is not present for the current - * platform. As such, we cannot write to the DTB at all and pass - * measured data. - */ - if (tb_fw_cfg_dtb == 0UL) { - panic(); - } - - /* Calculate hash */ - err = crypto_mod_calc_hash(MBEDTLS_MD_ID, - (void *)image_info.image_base, - image_info.image_size, hash_data); - if (err != 0) { - ERROR("%scalculate%s\n", "BL1: unable to ", - " BL2 hash"); - panic(); - } - - err = arm_set_bl2_hash_info((void *)tb_fw_cfg_dtb, hash_data); - if (err < 0) { - ERROR("%swrite%sdata%s\n", "BL1: unable to ", - " BL2 hash ", "to DTB\n"); - panic(); - } - - /* - * Ensure that the info written to the DTB is visible to other - * images. It's critical because BL2 won't be able to proceed - * without the heap info and its hash data. - */ - flush_dcache_range(tb_fw_cfg_dtb, fdt_totalsize((void *)tb_fw_cfg_dtb)); -} - -/* - * Reads TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB. - * Executed only from BL2. - */ -void arm_bl2_get_hash(void *data) -{ - const void *bl2_hash; - - assert(data != NULL); - - /* Retrieve TCG_DIGEST_SIZE bytes of BL2 hash data from the DTB */ - bl2_hash = FCONF_GET_PROPERTY(tbbr, dyn_config, bl2_hash_data); - (void)memcpy(data, bl2_hash, TCG_DIGEST_SIZE); -} -#endif /* MEASURED_BOOT */ #endif /* TRUSTED_BOARD_BOOT */ /* diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 5f20c8d48..8ebb6d602 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -20,18 +20,15 @@ #define DTB_PROP_MBEDTLS_HEAP_SIZE "mbedtls_heap_size" #if MEASURED_BOOT -#define DTB_PROP_BL2_HASH_DATA "bl2_hash_data" #ifdef SPD_opteed /* * Currently OP-TEE does not support reading DTBs from Secure memory * and this property should be removed when this feature is supported. */ #define DTB_PROP_HW_SM_LOG_ADDR "tpm_event_log_sm_addr" -#endif +#endif /* SPD_opteed */ #define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr" #define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size" - -static int dtb_root = -1; #endif /* MEASURED_BOOT */ /******************************************************************************* @@ -81,9 +78,8 @@ int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) */ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) { -#if !MEASURED_BOOT int dtb_root; -#endif + /* * Verify that the DTB is valid, before attempting to write to it, * and get the DTB root node. @@ -122,28 +118,6 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) } #if MEASURED_BOOT -/* - * This function writes the BL2 hash data in HW_FW_CONFIG DTB. - * When it is called, it is guaranteed that a DTB is available. - * - * This function is supposed to be called only by BL1. - * - * Returns: - * 0 = success - * < 0 = error - */ -int arm_set_bl2_hash_info(void *dtb, void *data) -{ - assert(dtb_root >= 0); - - /* - * Write the BL2 hash data in the DTB. - */ - return fdtw_write_inplace_bytes(dtb, dtb_root, - DTB_PROP_BL2_HASH_DATA, - TCG_DIGEST_SIZE, data); -} - /* * Write the Event Log address and its size in the DTB. * diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c index 1c6d68b2b..bcf9f8956 100644 --- a/plat/common/plat_bl1_common.c +++ b/plat/common/plat_bl1_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,9 +27,6 @@ #pragma weak bl1_plat_fwu_done #pragma weak bl1_plat_handle_pre_image_load #pragma weak bl1_plat_handle_post_image_load -#if MEASURED_BOOT -#pragma weak bl1_plat_set_bl2_hash -#endif unsigned int bl1_plat_get_next_image_id(void) { @@ -118,12 +115,3 @@ int bl1_plat_handle_post_image_load(unsigned int image_id) (void *) bl2_secram_layout); return 0; } - -#if MEASURED_BOOT -/* - * Calculates and writes BL2 hash data to TB_FW_CONFIG DTB. - */ -void bl1_plat_set_bl2_hash(const image_desc_t *image_desc) -{ -} -#endif -- cgit v1.2.3 From efa6521878ccb613919a1043537a6108f5ea59ed Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 14 Sep 2021 22:41:46 +0100 Subject: refactor(measured boot): remove platform calls from Event Log driver Currently, the Event Log driver does platform layer work by invoking a few platform functions in the 'event_log_finalise' call. Doing platform work does not seem to be the driver's responsibility, hence moved 'event_log_finalise' function's implementation to the platform layer. Alongside, introduced few Event Log driver functions and done some cosmetic changes. Change-Id: I486160e17e5b0677c734fd202af7ccd85476a551 Signed-off-by: Manish V Badarkhe --- drivers/measured_boot/event_log/event_log.c | 189 +++++++-------------- drivers/measured_boot/event_log/event_log.mk | 3 - .../drivers/measured_boot/event_log/event_log.h | 22 +-- include/plat/arm/common/plat_arm.h | 5 +- plat/arm/board/fvp/fvp_measured_boot.c | 70 +++++--- plat/arm/board/fvp/include/platform_def.h | 5 + plat/arm/common/arm_dyn_cfg_helpers.c | 18 +- 7 files changed, 132 insertions(+), 180 deletions(-) diff --git a/drivers/measured_boot/event_log/event_log.c b/drivers/measured_boot/event_log/event_log.c index ff771aa53..1755dd95e 100644 --- a/drivers/measured_boot/event_log/event_log.c +++ b/drivers/measured_boot/event_log/event_log.c @@ -17,22 +17,14 @@ #include -/* Event Log data */ -static uint8_t event_log[EVENT_LOG_SIZE]; +/* Running Event Log Pointer */ +static uint8_t *log_ptr; -/* End of Event Log */ -#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U) +/* Pointer to the first byte past end of the Event Log buffer */ +static uintptr_t log_end; -CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size); - -/* Pointer in event_log[] */ -static uint8_t *log_ptr = event_log; - -/* Pointer to measured_boot_data_t */ -const static measured_boot_data_t *plat_data_ptr; - -static uintptr_t tos_fw_config_base; -static uintptr_t nt_fw_config_base; +/* Pointer to event_log_metadata_t */ +static const event_log_metadata_t *plat_metadata_ptr; /* TCG_EfiSpecIdEvent */ static const id_event_headers_t id_event_header = { @@ -82,25 +74,28 @@ static const event2_header_t locality_event_header = { /* * Record a measurement as a TCG_PCR_EVENT2 event * - * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes - * @param[in] image_ptr Pointer to image_data_t structure + * @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes + * @param[in] metadata_ptr Pointer to event_log_metadata_t structure * * There must be room for storing this new event into the event log buffer. */ -void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) +static void event_log_record(const uint8_t *hash, + const event_log_metadata_t *metadata_ptr) { void *ptr = log_ptr; uint32_t name_len; - assert(image_ptr != NULL); - assert(image_ptr->name != NULL); assert(hash != NULL); + assert(metadata_ptr != NULL); + assert(metadata_ptr->name != NULL); + /* event_log_init() must have been called prior to this. */ + assert(log_ptr != NULL); - name_len = (uint32_t)strlen(image_ptr->name) + 1U; + name_len = (uint32_t)strlen(metadata_ptr->name) + 1U; /* Check for space in Event Log buffer */ - assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) <= - EVENT_LOG_END); + assert(((uintptr_t)ptr + (uint32_t)EVENT2_HDR_SIZE + name_len) < + log_end); /* * As per TCG specifications, firmware components that are measured @@ -108,7 +103,7 @@ void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) * EV_POST_CODE. */ /* TCG_PCR_EVENT2.PCRIndex */ - ((event2_header_t *)ptr)->pcr_index = image_ptr->pcr; + ((event2_header_t *)ptr)->pcr_index = metadata_ptr->pcr; /* TCG_PCR_EVENT2.EventType */ ((event2_header_t *)ptr)->event_type = EV_POST_CODE; @@ -136,7 +131,7 @@ void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) /* Copy event data to TCG_PCR_EVENT2.Event */ (void)memcpy((void *)(((event2_data_t *)ptr)->event), - (const void *)image_ptr->name, name_len); + (const void *)metadata_ptr->name, name_len); /* End of event data */ log_ptr = (uint8_t *)((uintptr_t)ptr + @@ -144,18 +139,38 @@ void event_log_record(const uint8_t *hash, const image_data_t *image_ptr) } /* - * Init Event Log + * Initialise Event Log global variables, used during the recording + * of various payload measurements into the Event Log buffer * + * @param[in] event_log_start Base address of Event Log buffer + * @param[in] event_log_finish End address of Event Log buffer, + * it is a first byte past end of the + * buffer + */ +void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish) +{ + assert(event_log_start != NULL); + assert(event_log_finish > event_log_start); + + log_ptr = event_log_start; + log_end = (uintptr_t)event_log_finish; + + /* Get pointer to platform's event_log_metadata_t structure */ + plat_metadata_ptr = plat_event_log_get_metadata(); + assert(plat_metadata_ptr != NULL); +} + +/* * Initialises Event Log by writing Specification ID and - * Startup Locality events. + * Startup Locality events */ -void event_log_init(void) +void event_log_write_header(void) { const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE; - void *ptr = event_log; + void *ptr = log_ptr; - /* Get pointer to platform's measured_boot_data_t structure */ - plat_data_ptr = plat_get_measured_boot_data(); + /* event_log_init() must have been called prior to this. */ + assert(log_ptr != NULL); /* * Add Specification ID Event first @@ -213,9 +228,7 @@ void event_log_init(void) * the platform's boot firmware */ ((startup_locality_event_t *)ptr)->startup_locality = 0U; - ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); - - log_ptr = (uint8_t *)ptr; + log_ptr = (uint8_t *)((uintptr_t)ptr + sizeof(startup_locality_event_t)); } /* @@ -232,23 +245,16 @@ void event_log_init(void) int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, uint32_t data_id) { - const image_data_t *data_ptr = plat_data_ptr->images_data; unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; int rc; + const event_log_metadata_t *metadata_ptr = plat_metadata_ptr; /* Get the metadata associated with this image. */ - while ((data_ptr->id != INVALID_ID) && (data_ptr->id != data_id)) { - data_ptr++; - } - assert(data_ptr->id != INVALID_ID); - - if (data_id == TOS_FW_CONFIG_ID) { - tos_fw_config_base = data_base; - } else if (data_id == NT_FW_CONFIG_ID) { - nt_fw_config_base = data_base; - } else { - /* No action */ + while ((metadata_ptr->id != INVALID_ID) && + (metadata_ptr->id != data_id)) { + metadata_ptr++; } + assert(metadata_ptr->id != INVALID_ID); /* Calculate hash */ rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID, @@ -257,97 +263,22 @@ int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, return rc; } - event_log_record(hash_data, data_ptr); + event_log_record(hash_data, metadata_ptr); return 0; } /* - * Finalise Event Log + * Get current Event Log buffer size i.e. used space of Event Log buffer * - * @param[out] log_addr Pointer to return Event Log address - * @param[out] log_size Pointer to return Event Log size - * @return: - * 0 = success - * < 0 = error code + * @param[in] event_log_start Base Pointer to Event Log buffer + * + * @return: current Size of Event Log buffer */ -int event_log_finalise(uint8_t **log_addr, size_t *log_size) +size_t event_log_get_cur_size(uint8_t *event_log_start) { - /* Event Log size */ - size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log; - int rc; - - assert(log_addr != NULL); - assert(log_size != NULL); - - if (nt_fw_config_base == 0UL) { - ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT"); - return -ENOENT; - } - - /* - * Set Event Log data in NT_FW_CONFIG and - * get Event Log address in Non-Secure memory - */ - if (plat_data_ptr->set_nt_fw_info != NULL) { - - /* Event Log address in Non-Secure memory */ - uintptr_t ns_log_addr; - - rc = plat_data_ptr->set_nt_fw_info( - nt_fw_config_base, -#ifdef SPD_opteed - (uintptr_t)event_log, -#endif - num_bytes, &ns_log_addr); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "NT"); - return rc; - } - - /* Copy Event Log to Non-secure memory */ - (void)memcpy((void *)ns_log_addr, (const void *)event_log, - num_bytes); - - /* Ensure that the Event Log is visible in Non-secure memory */ - flush_dcache_range(ns_log_addr, num_bytes); - - /* Return Event Log address in Non-Secure memory */ - *log_addr = (uint8_t *)ns_log_addr; - - } else { - INFO("%s(): set_%s_fw_info not set\n", __func__, "nt"); - - /* Return Event Log address in Secure memory */ - *log_addr = event_log; - } - - if (tos_fw_config_base != 0UL) { - if (plat_data_ptr->set_tos_fw_info != NULL) { - - /* Set Event Log data in TOS_FW_CONFIG */ - rc = plat_data_ptr->set_tos_fw_info( - tos_fw_config_base, - (uintptr_t)event_log, - num_bytes); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "TOS"); - return rc; - } - } else { - INFO("%s(): set_%s_fw_info not set\n", __func__, "tos"); - } - } else { - INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS"); - } + assert(event_log_start != NULL); + assert(log_ptr >= event_log_start); - /* Ensure that the Event Log is visible in Secure memory */ - flush_dcache_range((uintptr_t)event_log, num_bytes); - - /* Return Event Log size */ - *log_size = num_bytes; - - return 0; + return (size_t)((uintptr_t)log_ptr - (uintptr_t)event_log_start); } diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk index 34bde171e..e42f9c98b 100644 --- a/drivers/measured_boot/event_log/event_log.mk +++ b/drivers/measured_boot/event_log/event_log.mk @@ -25,8 +25,6 @@ else TCG_DIGEST_SIZE := 32U endif -# Event Log length in bytes -EVENT_LOG_SIZE := 1024 # Set definitions for mbed TLS library and Measured Boot driver $(eval $(call add_defines,\ @@ -34,7 +32,6 @@ $(eval $(call add_defines,\ MBEDTLS_MD_ID \ TPM_ALG_ID \ TCG_DIGEST_SIZE \ - EVENT_LOG_SIZE \ EVENT_LOG_LEVEL \ ))) diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h index 96fdc2faa..9aa6dc741 100644 --- a/include/drivers/measured_boot/event_log/event_log.h +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -10,6 +10,7 @@ #include #include +#include #include /* @@ -59,18 +60,7 @@ typedef struct { unsigned int id; const char *name; unsigned int pcr; -} image_data_t; - -typedef struct { - const image_data_t *images_data; - int (*set_nt_fw_info)(uintptr_t config_base, -#ifdef SPD_opteed - uintptr_t log_addr, -#endif - size_t log_size, uintptr_t *ns_log_addr); - int (*set_tos_fw_info)(uintptr_t config_base, uintptr_t log_addr, - size_t log_size); -} measured_boot_data_t; +} event_log_metadata_t; #define ID_EVENT_SIZE (sizeof(id_event_headers_t) + \ (sizeof(id_event_algorithm_size_t) * HASH_ALG_COUNT) + \ @@ -88,12 +78,12 @@ typedef struct { sizeof(event2_data_t)) /* Functions' declarations */ -void event_log_init(void); -int event_log_finalise(uint8_t **log_addr, size_t *log_size); +void event_log_init(uint8_t *event_log_start, uint8_t *event_log_finish); +void event_log_write_header(void); void dump_event_log(uint8_t *log_addr, size_t log_size); -const measured_boot_data_t *plat_get_measured_boot_data(void); +const event_log_metadata_t *plat_event_log_get_metadata(void); int event_log_measure_and_record(uintptr_t data_base, uint32_t data_size, uint32_t data_id); -void event_log_record(const uint8_t *hash, const image_data_t *image_ptr); +size_t event_log_get_cur_size(uint8_t *event_log_start); #endif /* EVENT_LOG_H */ diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 57e6953ab..5765226cb 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -250,9 +250,8 @@ void arm_bl1_set_mbedtls_heap(void); int arm_get_mbedtls_heap(void **heap_addr, size_t *heap_size); #if MEASURED_BOOT -int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, - size_t log_size); -int arm_set_nt_fw_info(uintptr_t config_base, +int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size); +int arm_set_nt_fw_info( /* * Currently OP-TEE does not support reading DTBs from Secure memory * and this option should be removed when feature is supported. diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c index f0de7521e..83419b681 100644 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ b/plat/arm/board/fvp/fvp_measured_boot.c @@ -1,21 +1,19 @@ /* - * Copyright (c) 2020-2021, Arm Limited. All rights reserved. + * Copyright (c) 2021, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include #include -#include #include - #include -#include + +/* Event Log data */ +static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; /* FVP table with platform specific image IDs, names and PCRs */ -static const image_data_t fvp_images_data[] = { - { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ +const event_log_metadata_t fvp_event_log_metadata[] = { { BL31_IMAGE_ID, BL31_STRING, PCR_0 }, { BL32_IMAGE_ID, BL32_STRING, PCR_0 }, { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, @@ -29,42 +27,66 @@ static const image_data_t fvp_images_data[] = { { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; -static const measured_boot_data_t fvp_measured_boot_data = { - fvp_images_data, - arm_set_nt_fw_info, - arm_set_tos_fw_info -}; - -/* - * Function retuns pointer to FVP plat_measured_boot_data_t structure - */ -const measured_boot_data_t *plat_get_measured_boot_data(void) +const event_log_metadata_t *plat_event_log_get_metadata(void) { - return &fvp_measured_boot_data; + return fvp_event_log_metadata; } void bl2_plat_mboot_init(void) { - event_log_init(); + event_log_init(event_log, event_log + sizeof(event_log)); + event_log_write_header(); } void bl2_plat_mboot_finish(void) { - uint8_t *log_addr; - size_t log_size; int rc; - rc = event_log_finalise(&log_addr, &log_size); + /* Event Log address in Non-Secure memory */ + uintptr_t ns_log_addr; + + /* Event Log filled size */ + size_t event_log_cur_size; + + event_log_cur_size = event_log_get_cur_size(event_log); + + rc = arm_set_nt_fw_info( +#ifdef SPD_opteed + (uintptr_t)event_log, +#endif + event_log_cur_size, &ns_log_addr); if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "NT"); /* * It is a fatal error because on FVP secure world software * assumes that a valid event log exists and will use it to - * record the measurements into the fTPM + * record the measurements into the fTPM. + * Note: In FVP platform, OP-TEE uses nt_fw_config to get the + * secure Event Log buffer address. */ panic(); } - dump_event_log(log_addr, log_size); + /* Copy Event Log to Non-secure memory */ + (void)memcpy((void *)ns_log_addr, (const void *)event_log, + event_log_cur_size); + + /* Ensure that the Event Log is visible in Non-secure memory */ + flush_dcache_range(ns_log_addr, event_log_cur_size); + +#if defined(SPD_tspd) || defined(SPD_spmd) + /* Set Event Log data in TOS_FW_CONFIG */ + rc = arm_set_tos_fw_info((uintptr_t)event_log, + event_log_cur_size); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "TOS"); + panic(); + } +#endif + + dump_event_log(event_log, event_log_cur_size); } int plat_mboot_measure_image(unsigned int image_id) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 96574e526..d89e122c8 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -341,4 +341,9 @@ #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #endif +/* + * Maximum size of Event Log buffer used in Measured Boot Event Log driver + */ +#define PLAT_ARM_EVENT_LOG_MAX_SIZE UL(0x400) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 8ebb6d602..33f2e495e 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -205,14 +205,20 @@ static int arm_set_event_log_info(uintptr_t config_base, * 0 = success * < 0 = error */ -int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, - size_t log_size) +int arm_set_tos_fw_info(uintptr_t log_addr, size_t log_size) { + uintptr_t config_base; + const bl_mem_params_node_t *cfg_mem_params; int err; - assert(config_base != 0UL); assert(log_addr != 0UL); + /* Get the config load address and size of TOS_FW_CONFIG */ + cfg_mem_params = get_bl_mem_params_node(TOS_FW_CONFIG_ID); + assert(cfg_mem_params != NULL); + + config_base = cfg_mem_params->image_info.image_base; + /* Write the Event Log address and its size in the DTB */ err = arm_set_event_log_info(config_base, #ifdef SPD_opteed @@ -237,23 +243,25 @@ int arm_set_tos_fw_info(uintptr_t config_base, uintptr_t log_addr, * 0 = success * < 0 = error */ -int arm_set_nt_fw_info(uintptr_t config_base, +int arm_set_nt_fw_info( #ifdef SPD_opteed uintptr_t log_addr, #endif size_t log_size, uintptr_t *ns_log_addr) { + uintptr_t config_base; uintptr_t ns_addr; const bl_mem_params_node_t *cfg_mem_params; int err; - assert(config_base != 0UL); assert(ns_log_addr != NULL); /* Get the config load address and size from NT_FW_CONFIG */ cfg_mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); assert(cfg_mem_params != NULL); + config_base = cfg_mem_params->image_info.image_base; + /* Calculate Event Log address in Non-secure memory */ ns_addr = cfg_mem_params->image_info.image_base + cfg_mem_params->image_info.image_max_size; -- cgit v1.2.3 From 48ba0345f7b42880ec4442d7e90e3e1af95feadd Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Tue, 14 Sep 2021 23:12:42 +0100 Subject: feat(measured_boot): image hash measurement and recording in BL1 It looks safer and cleaner approach to record the measurement taken by BL1 straightaway in TCG Event Log instead of deferring these recordings to BL2. Hence pull in the full-fledged measured boot driver into BL1 that replaces the former ad-hoc platform interfaces i.e. bl1_plat_set_bl2_hash, bl2_plat_get_hash. As a result of this change the BL1 of Arm FVP platform now do the measurements and recordings of below images: 1. FW_CONFIG 2. TB_FW_CONFIG 3. BL2 Change-Id: I798c20336308b5e91b547da4f8ed57c24d490731 Signed-off-by: Manish V Badarkhe --- bl1/bl1_main.c | 8 +- common/bl_common.c | 5 +- drivers/measured_boot/event_log/event_log.mk | 1 + .../drivers/measured_boot/event_log/event_log.h | 2 + include/plat/common/platform.h | 27 ++++- plat/arm/board/fvp/fvp_bl1_measured_boot.c | 33 ++++++ plat/arm/board/fvp/fvp_bl2_measured_boot.c | 85 +++++++++++++++ plat/arm/board/fvp/fvp_common_measured_boot.c | 35 +++++++ plat/arm/board/fvp/fvp_measured_boot.c | 114 --------------------- plat/arm/board/fvp/platform.mk | 5 +- 10 files changed, 191 insertions(+), 124 deletions(-) create mode 100644 plat/arm/board/fvp/fvp_bl1_measured_boot.c create mode 100644 plat/arm/board/fvp/fvp_bl2_measured_boot.c create mode 100644 plat/arm/board/fvp/fvp_common_measured_boot.c delete mode 100644 plat/arm/board/fvp/fvp_measured_boot.c diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index fd602324f..663ec642b 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -126,6 +126,9 @@ void bl1_main(void) auth_mod_init(); #endif /* TRUSTED_BOARD_BOOT */ + /* Initialize the measured boot */ + bl1_plat_mboot_init(); + /* Perform platform setup in BL1. */ bl1_platform_setup(); @@ -147,6 +150,9 @@ void bl1_main(void) else NOTICE("BL1-FWU: *******FWU Process Started*******\n"); + /* Teardown the measured boot driver */ + bl1_plat_mboot_finish(); + bl1_prepare_next_image(image_id); console_flush(); diff --git a/common/bl_common.c b/common/bl_common.c index 3c37bcfa2..eb2352a77 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -203,7 +203,6 @@ static int load_auth_image_recursive(unsigned int image_id, } if (is_parent_image == 0) { -#if IMAGE_BL2 /* * Measure the image. * We do not measure its parents because these only play a role @@ -212,11 +211,11 @@ static int load_auth_image_recursive(unsigned int image_id, * TODO: Change this code if we change our minds about measuring * certificates. */ - rc = plat_mboot_measure_image(image_id); + rc = plat_mboot_measure_image(image_id, image_data); if (rc != 0) { return rc; } -#endif + /* * Flush the image to main memory so that it can be executed * later by any CPU, regardless of cache and MMU state. This diff --git a/drivers/measured_boot/event_log/event_log.mk b/drivers/measured_boot/event_log/event_log.mk index e42f9c98b..37e5e291d 100644 --- a/drivers/measured_boot/event_log/event_log.mk +++ b/drivers/measured_boot/event_log/event_log.mk @@ -47,3 +47,4 @@ MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}event_log.c \ ${MEASURED_BOOT_SRC_DIR}event_print.c BL2_SOURCES += ${MEASURED_BOOT_SOURCES} +BL1_SOURCES += ${MEASURED_BOOT_SOURCES} diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h index 9aa6dc741..0d22d876d 100644 --- a/include/drivers/measured_boot/event_log/event_log.h +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -48,12 +48,14 @@ #define BL32_EXTRA1_IMAGE_STRING "BL32_EXTRA1_IMAGE" #define BL32_EXTRA2_IMAGE_STRING "BL32_EXTRA2_IMAGE" #define BL33_STRING "BL_33" +#define FW_CONFIG_STRING "FW_CONFIG" #define GPT_IMAGE_STRING "GPT" #define HW_CONFIG_STRING "HW_CONFIG" #define NT_FW_CONFIG_STRING "NT_FW_CONFIG" #define SCP_BL2_IMAGE_STRING "SCP_BL2_IMAGE" #define SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" #define STM32_IMAGE_STRING "STM32" +#define TB_FW_CONFIG_STRING "TB_FW_CONFIG" #define TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" typedef struct { diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index c7c4dcb39..3fa63f555 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -122,6 +122,16 @@ const char *plat_log_get_prefix(unsigned int log_level); void bl2_plat_preload_setup(void); int plat_try_next_boot_source(void); +#if MEASURED_BOOT +int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data); +#else +static inline int plat_mboot_measure_image(unsigned int image_id __unused, + image_info_t *image_data __unused) +{ + return 0; +} +#endif /* MEASURED_BOOT */ + /******************************************************************************* * Mandatory BL1 functions ******************************************************************************/ @@ -181,6 +191,18 @@ __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved); int bl1_plat_handle_pre_image_load(unsigned int image_id); int bl1_plat_handle_post_image_load(unsigned int image_id); +#if MEASURED_BOOT +void bl1_plat_mboot_init(void); +void bl1_plat_mboot_finish(void); +#else +static inline void bl1_plat_mboot_init(void) +{ +} +static inline void bl1_plat_mboot_finish(void) +{ +} +#endif /* MEASURED_BOOT */ + /******************************************************************************* * Mandatory BL2 functions ******************************************************************************/ @@ -202,7 +224,6 @@ int bl2_plat_handle_post_image_load(unsigned int image_id); #if MEASURED_BOOT void bl2_plat_mboot_init(void); void bl2_plat_mboot_finish(void); -int plat_mboot_measure_image(unsigned int image_id); #else static inline void bl2_plat_mboot_init(void) { @@ -210,10 +231,6 @@ static inline void bl2_plat_mboot_init(void) static inline void bl2_plat_mboot_finish(void) { } -static inline int plat_mboot_measure_image(unsigned int image_id __unused) -{ - return 0; -} #endif /* MEASURED_BOOT */ /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c new file mode 100644 index 000000000..15ea05997 --- /dev/null +++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +/* Event Log data */ +static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; + +/* FVP table with platform specific image IDs, names and PCRs */ +const event_log_metadata_t fvp_event_log_metadata[] = { + { FW_CONFIG_ID, FW_CONFIG_STRING, PCR_0 }, + { TB_FW_CONFIG_ID, TB_FW_CONFIG_STRING, PCR_0 }, + { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, + { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ +}; + +void bl1_plat_mboot_init(void) +{ + event_log_init(event_log, PLAT_ARM_EVENT_LOG_MAX_SIZE, 0U); +} + +void bl1_plat_mboot_finish(void) +{ + /* + * ToDo: populate tb_fw_config with Event Log address, its maximum size + * and filled size + */ +} diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c new file mode 100644 index 000000000..f5d829a23 --- /dev/null +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/* Event Log data */ +static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; + +/* FVP table with platform specific image IDs, names and PCRs */ +const event_log_metadata_t fvp_event_log_metadata[] = { + { BL31_IMAGE_ID, BL31_STRING, PCR_0 }, + { BL32_IMAGE_ID, BL32_STRING, PCR_0 }, + { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, + { BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 }, + { BL33_IMAGE_ID, BL33_STRING, PCR_0 }, + { HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 }, + { NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 }, + { SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 }, + { SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 }, + { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, + { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ +}; + +void bl2_plat_mboot_init(void) +{ + event_log_init(event_log, event_log + sizeof(event_log)); + event_log_write_header(); +} + +void bl2_plat_mboot_finish(void) +{ + int rc; + + /* Event Log address in Non-Secure memory */ + uintptr_t ns_log_addr; + + /* Event Log filled size */ + size_t event_log_cur_size; + + event_log_cur_size = event_log_get_cur_size(event_log); + + rc = arm_set_nt_fw_info( +#ifdef SPD_opteed + (uintptr_t)event_log, +#endif + event_log_cur_size, &ns_log_addr); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "NT"); + /* + * It is a fatal error because on FVP secure world software + * assumes that a valid event log exists and will use it to + * record the measurements into the fTPM. + * Note: In FVP platform, OP-TEE uses nt_fw_config to get the + * secure Event Log buffer address. + */ + panic(); + } + + /* Copy Event Log to Non-secure memory */ + (void)memcpy((void *)ns_log_addr, (const void *)event_log, + event_log_cur_size); + + /* Ensure that the Event Log is visible in Non-secure memory */ + flush_dcache_range(ns_log_addr, event_log_cur_size); + +#if defined(SPD_tspd) || defined(SPD_spmd) + /* Set Event Log data in TOS_FW_CONFIG */ + rc = arm_set_tos_fw_info((uintptr_t)event_log, + event_log_cur_size); + if (rc != 0) { + ERROR("%s(): Unable to update %s_FW_CONFIG\n", + __func__, "TOS"); + panic(); + } +#endif + + dump_event_log(event_log, event_log_cur_size); +} diff --git a/plat/arm/board/fvp/fvp_common_measured_boot.c b/plat/arm/board/fvp/fvp_common_measured_boot.c new file mode 100644 index 000000000..6a403d945 --- /dev/null +++ b/plat/arm/board/fvp/fvp_common_measured_boot.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +extern event_log_metadata_t fvp_event_log_metadata[]; + +const event_log_metadata_t *plat_event_log_get_metadata(void) +{ + return fvp_event_log_metadata; +} + +int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data) +{ + /* Calculate image hash and record data in Event Log */ + int err = event_log_measure_and_record(image_data->image_base, + image_data->image_size, + image_id); + if (err != 0) { + ERROR("%s%s image id %u (%i)\n", + "Failed to ", "record", image_id, err); + return err; + } + + return 0; +} diff --git a/plat/arm/board/fvp/fvp_measured_boot.c b/plat/arm/board/fvp/fvp_measured_boot.c deleted file mode 100644 index 83419b681..000000000 --- a/plat/arm/board/fvp/fvp_measured_boot.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -/* Event Log data */ -static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; - -/* FVP table with platform specific image IDs, names and PCRs */ -const event_log_metadata_t fvp_event_log_metadata[] = { - { BL31_IMAGE_ID, BL31_STRING, PCR_0 }, - { BL32_IMAGE_ID, BL32_STRING, PCR_0 }, - { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, - { BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 }, - { BL33_IMAGE_ID, BL33_STRING, PCR_0 }, - { HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 }, - { NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 }, - { SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 }, - { SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 }, - { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, - { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ -}; - -const event_log_metadata_t *plat_event_log_get_metadata(void) -{ - return fvp_event_log_metadata; -} - -void bl2_plat_mboot_init(void) -{ - event_log_init(event_log, event_log + sizeof(event_log)); - event_log_write_header(); -} - -void bl2_plat_mboot_finish(void) -{ - int rc; - - /* Event Log address in Non-Secure memory */ - uintptr_t ns_log_addr; - - /* Event Log filled size */ - size_t event_log_cur_size; - - event_log_cur_size = event_log_get_cur_size(event_log); - - rc = arm_set_nt_fw_info( -#ifdef SPD_opteed - (uintptr_t)event_log, -#endif - event_log_cur_size, &ns_log_addr); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "NT"); - /* - * It is a fatal error because on FVP secure world software - * assumes that a valid event log exists and will use it to - * record the measurements into the fTPM. - * Note: In FVP platform, OP-TEE uses nt_fw_config to get the - * secure Event Log buffer address. - */ - panic(); - } - - /* Copy Event Log to Non-secure memory */ - (void)memcpy((void *)ns_log_addr, (const void *)event_log, - event_log_cur_size); - - /* Ensure that the Event Log is visible in Non-secure memory */ - flush_dcache_range(ns_log_addr, event_log_cur_size); - -#if defined(SPD_tspd) || defined(SPD_spmd) - /* Set Event Log data in TOS_FW_CONFIG */ - rc = arm_set_tos_fw_info((uintptr_t)event_log, - event_log_cur_size); - if (rc != 0) { - ERROR("%s(): Unable to update %s_FW_CONFIG\n", - __func__, "TOS"); - panic(); - } -#endif - - dump_event_log(event_log, event_log_cur_size); -} - -int plat_mboot_measure_image(unsigned int image_id) -{ - const bl_mem_params_node_t *bl_mem_params = - get_bl_mem_params_node(image_id); - - assert(bl_mem_params != NULL); - - image_info_t info = bl_mem_params->image_info; - int err; - - if ((info.h.attr & IMAGE_ATTRIB_SKIP_LOADING) == 0U) { - /* Calculate image hash and record data in Event Log */ - err = event_log_measure_record(info.image_base, - info.image_size, image_id); - if (err != 0) { - ERROR("%s%s image id %u (%i)\n", - "BL2: Failed to ", "record", image_id, err); - return err; - } - } - - return 0; -} diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index b37514626..70b1051a8 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -376,7 +376,10 @@ BL1_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c BL2_SOURCES += plat/arm/board/fvp/fvp_trusted_boot.c ifeq (${MEASURED_BOOT},1) -BL2_SOURCES += plat/arm/board/fvp/fvp_measured_boot.c +BL1_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \ + plat/arm/board/fvp/fvp_bl1_measured_boot.c +BL2_SOURCES += plat/arm/board/fvp/fvp_common_measured_boot.c \ + plat/arm/board/fvp/fvp_bl2_measured_boot.c endif # FVP being a development platform, enable capability to disable Authentication -- cgit v1.2.3 From e742bcdae0d28dc14a2aa0b4ca30f50420bb5ebe Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 11 Aug 2021 10:45:03 +0100 Subject: feat(measured_boot): update tb_fw_config with event log properties Making tb_fw_config ready to pass the Event Log base address and size information to BL2. Change-Id: I5dd0e79007e3848b5d6d0e69275a46c2e9807a98 Signed-off-by: Manish V Badarkhe --- docs/components/measured_boot/event_log.rst | 2 +- plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/components/measured_boot/event_log.rst b/docs/components/measured_boot/event_log.rst index 5347dcc19..088124825 100644 --- a/docs/components/measured_boot/event_log.rst +++ b/docs/components/measured_boot/event_log.rst @@ -9,7 +9,7 @@ Dynamic configuration for Event Log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Measured Boot driver expects a *tpm_event_log* node with the following field -in 'nt_fw_config' and 'tsp_fw_config' DTS files: +in 'tb_fw_config', 'nt_fw_config' and 'tsp_fw_config' DTS files: - compatible [mandatory] - value type: diff --git a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts index 9e5b59a71..cf4ef2d02 100644 --- a/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts @@ -104,6 +104,10 @@ #include "cot_descriptors.dtsi" #endif +#if MEASURED_BOOT + #include "event_log.dtsi" +#endif + }; #if COT_DESC_IN_DTB -- cgit v1.2.3 From 0500f4479eb1d0d5ab9e83dac42b633a5ff677dd Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 11 Aug 2021 10:45:03 +0100 Subject: feat(plat/fvp): pass Event Log addr and size from BL1 to BL2 Introduced functions to set and get Event log information (tpm_event_log address and its size). In FVP platform case, measured boot with Event Log backend flow work as below 1. event_log_init function called by BL1 to initialize Event Log module 2. arm_set_tb_fw_info function called by BL1 to set the 'tpm_event_log_addr' and 'tpm_event_log_size' properties in tb_fw_config 3. arm_get_tb_fw_info function called by BL2 to get tpm Event Log parameters set by BL1. These parameters used by the BL2 to extend the tpm Event Log records, and use these parameters to initialize Event Log using event_log_init function 4. arm_set_nt_fw_info and arm_set_tos_fw_info function called by BL2 to set 'tpm_event_log' address and its size properties in nt_fw_config and tos_fw_config respectively Alongside, this patch created a separate instances of plat_mboot_init and plat_mboot_finish APIs for BL1 and BL2. This patch is tested using the existing measured boot test configuration in jenkins CI. Change-Id: Ib9eca092afe580df014541c937868f921dff9c37 Signed-off-by: Manish V Badarkhe --- include/plat/arm/common/plat_arm.h | 2 + plat/arm/board/fvp/fvp_bl1_measured_boot.c | 21 ++++++-- plat/arm/board/fvp/fvp_bl2_measured_boot.c | 43 +++++++++++---- plat/arm/common/arm_dyn_cfg_helpers.c | 87 +++++++++++++++++++++++++++++- 4 files changed, 137 insertions(+), 16 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 5765226cb..9618700a2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -260,6 +260,8 @@ int arm_set_nt_fw_info( uintptr_t log_addr, #endif size_t log_size, uintptr_t *ns_log_addr); +int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size); +int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size); #endif /* MEASURED_BOOT */ /* diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c index 15ea05997..8815b74e4 100644 --- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c @@ -7,6 +7,7 @@ #include #include +#include /* Event Log data */ static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; @@ -21,13 +22,23 @@ const event_log_metadata_t fvp_event_log_metadata[] = { void bl1_plat_mboot_init(void) { - event_log_init(event_log, PLAT_ARM_EVENT_LOG_MAX_SIZE, 0U); + event_log_init(event_log, event_log + sizeof(event_log)); + event_log_write_header(); } void bl1_plat_mboot_finish(void) { - /* - * ToDo: populate tb_fw_config with Event Log address, its maximum size - * and filled size - */ + size_t event_log_cur_size; + + event_log_cur_size = event_log_get_cur_size(event_log); + int rc = arm_set_tb_fw_info((uintptr_t)event_log, + event_log_cur_size); + if (rc != 0) { + /* + * It is a fatal error because on FVP platform, BL2 software + * assumes that a valid Event Log buffer exist and it will use + * same Event Log buffer to append image measurements. + */ + panic(); + } } diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c index f5d829a23..16e8d79ee 100644 --- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -10,7 +10,7 @@ #include /* Event Log data */ -static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; +static uint64_t event_log_base; /* FVP table with platform specific image IDs, names and PCRs */ const event_log_metadata_t fvp_event_log_metadata[] = { @@ -29,8 +29,33 @@ const event_log_metadata_t fvp_event_log_metadata[] = { void bl2_plat_mboot_init(void) { - event_log_init(event_log, event_log + sizeof(event_log)); - event_log_write_header(); + uint8_t *event_log_start; + uint8_t *event_log_finish; + size_t bl1_event_log_size; + int rc; + + rc = arm_get_tb_fw_info(&event_log_base, &bl1_event_log_size); + if (rc != 0) { + ERROR("%s(): Unable to get Event Log info from TB_FW_CONFIG\n", + __func__); + /* + * It is a fatal error because on FVP platform, BL2 software + * assumes that a valid Event Log buffer exist and it will use + * same Event Log buffer to append image measurements. + */ + panic(); + } + + /* + * BL1 and BL2 share the same Event Log buffer and that BL2 will + * append its measurements after BL1's + */ + event_log_start = (uint8_t *)((uintptr_t)event_log_base + + bl1_event_log_size); + event_log_finish = (uint8_t *)((uintptr_t)event_log_base + + PLAT_ARM_EVENT_LOG_MAX_SIZE); + + event_log_init((uint8_t *)event_log_start, event_log_finish); } void bl2_plat_mboot_finish(void) @@ -43,11 +68,11 @@ void bl2_plat_mboot_finish(void) /* Event Log filled size */ size_t event_log_cur_size; - event_log_cur_size = event_log_get_cur_size(event_log); + event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); rc = arm_set_nt_fw_info( #ifdef SPD_opteed - (uintptr_t)event_log, + (uintptr_t)event_log_base, #endif event_log_cur_size, &ns_log_addr); if (rc != 0) { @@ -64,7 +89,7 @@ void bl2_plat_mboot_finish(void) } /* Copy Event Log to Non-secure memory */ - (void)memcpy((void *)ns_log_addr, (const void *)event_log, + (void)memcpy((void *)ns_log_addr, (const void *)event_log_base, event_log_cur_size); /* Ensure that the Event Log is visible in Non-secure memory */ @@ -72,14 +97,14 @@ void bl2_plat_mboot_finish(void) #if defined(SPD_tspd) || defined(SPD_spmd) /* Set Event Log data in TOS_FW_CONFIG */ - rc = arm_set_tos_fw_info((uintptr_t)event_log, + rc = arm_set_tos_fw_info((uintptr_t)event_log_base, event_log_cur_size); if (rc != 0) { ERROR("%s(): Unable to update %s_FW_CONFIG\n", __func__, "TOS"); panic(); } -#endif +#endif /* defined(SPD_tspd) || defined(SPD_spmd) */ - dump_event_log(event_log, event_log_cur_size); + dump_event_log((uint8_t *)event_log_base, event_log_cur_size); } diff --git a/plat/arm/common/arm_dyn_cfg_helpers.c b/plat/arm/common/arm_dyn_cfg_helpers.c index 33f2e495e..6a2a6f89a 100644 --- a/plat/arm/common/arm_dyn_cfg_helpers.c +++ b/plat/arm/common/arm_dyn_cfg_helpers.c @@ -11,6 +11,8 @@ #endif #include +#include +#include #include #include @@ -121,8 +123,6 @@ int arm_set_dtb_mbedtls_heap_info(void *dtb, void *heap_addr, size_t heap_size) /* * Write the Event Log address and its size in the DTB. * - * This function is supposed to be called only by BL2. - * * Returns: * 0 = success * < 0 = error @@ -282,4 +282,87 @@ int arm_set_nt_fw_info( *ns_log_addr = (err < 0) ? 0UL : ns_addr; return err; } + +/* + * This function writes the Event Log address and its size + * in the TB_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL1. + * + * Returns: + * 0 = success + * < 0 = error + */ +int arm_set_tb_fw_info(uintptr_t log_addr, size_t log_size) +{ + /* + * Read tb_fw_config device tree for Event Log properties + * and write the Event Log address and its size in the DTB + */ + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + uintptr_t tb_fw_cfg_dtb; + int err; + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + tb_fw_cfg_dtb = tb_fw_config_info->config_addr; + + err = arm_set_event_log_info(tb_fw_cfg_dtb, +#ifdef SPD_opteed + 0UL, +#endif + log_addr, log_size); + return err; +} + +/* + * This function reads the Event Log address and its size + * properties present in TB_FW_CONFIG DTB. + * + * This function is supposed to be called only by BL2. + * + * Returns: + * 0 = success + * < 0 = error + * Alongside returns Event Log address and its size. + */ + +int arm_get_tb_fw_info(uint64_t *log_addr, size_t *log_size) +{ + /* As libfdt uses void *, we can't avoid this cast */ + const struct dyn_cfg_dtb_info_t *tb_fw_config_info; + int node, rc; + + tb_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, TB_FW_CONFIG_ID); + assert(tb_fw_config_info != NULL); + + void *dtb = (void *)tb_fw_config_info->config_addr; + const char *compatible = "arm,tpm_event_log"; + + /* Assert the node offset point to compatible property */ + node = fdt_node_offset_by_compatible(dtb, -1, compatible); + if (node < 0) { + WARN("The compatible property '%s'%s", compatible, + " not specified in TB_FW config.\n"); + return node; + } + + VERBOSE("Dyn cfg: '%s'%s", compatible, " found in the config\n"); + + rc = fdt_read_uint64(dtb, node, DTB_PROP_HW_LOG_ADDR, log_addr); + if (rc != 0) { + ERROR("%s%s", DTB_PROP_HW_LOG_ADDR, + " not specified in TB_FW config.\n"); + return rc; + } + + rc = fdt_read_uint32(dtb, node, DTB_PROP_HW_LOG_SIZE, (uint32_t *)log_size); + if (rc != 0) { + ERROR("%s%s", DTB_PROP_HW_LOG_SIZE, + " not specified in TB_FW config.\n"); + } + + return rc; +} #endif /* MEASURED_BOOT */ -- cgit v1.2.3 From 8a89e1898b87780ec729524395da3b263ce0f884 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Wed, 8 Sep 2021 20:04:24 +0100 Subject: refactor(measured boot): make measurement strings compliant with SBSG Made measurement strings compliant to Server Base Security Guide (SBSG, Arm DEN 0086) hence updated measurement strings for BL32, BL31, and SCP_BL2 images. As the GPT image is not get measured by BL2 so removed its measurement string. Also, namespaced measurement string defines that were looking quite generic. Change-Id: Iaa17c0cfeee3d06dc822eff2bd553da23bd99b76 Signed-off-by: Manish V Badarkhe --- .../drivers/measured_boot/event_log/event_log.h | 50 +++++++++++++++------- plat/arm/board/fvp/fvp_bl1_measured_boot.c | 6 +-- plat/arm/board/fvp/fvp_bl2_measured_boot.c | 20 ++++----- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h index 0d22d876d..c6eb29cfe 100644 --- a/include/drivers/measured_boot/event_log/event_log.h +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -42,21 +42,41 @@ #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) -#define BL2_STRING "BL_2" -#define BL31_STRING "BL_31" -#define BL32_STRING "BL_32" -#define BL32_EXTRA1_IMAGE_STRING "BL32_EXTRA1_IMAGE" -#define BL32_EXTRA2_IMAGE_STRING "BL32_EXTRA2_IMAGE" -#define BL33_STRING "BL_33" -#define FW_CONFIG_STRING "FW_CONFIG" -#define GPT_IMAGE_STRING "GPT" -#define HW_CONFIG_STRING "HW_CONFIG" -#define NT_FW_CONFIG_STRING "NT_FW_CONFIG" -#define SCP_BL2_IMAGE_STRING "SCP_BL2_IMAGE" -#define SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" -#define STM32_IMAGE_STRING "STM32" -#define TB_FW_CONFIG_STRING "TB_FW_CONFIG" -#define TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" +/* + * Each event log entry has some metadata (i.e. a string) that identifies + * what is measured.These macros define these strings. + * Note that these strings follow the standardization recommendations + * defined in the Arm Server Base Security Guide (a.k.a. SBSG, Arm DEN 0086), + * where applicable. They should not be changed in the code. + * Where the SBSG does not make recommendations, we are free to choose any + * naming convention. + * The key thing is to choose meaningful strings so that when the TPM event + * log is used in attestation, the different components can be identified. + */ +#define EVLOG_BL2_STRING "BL_2" +#define EVLOG_BL31_STRING "SECURE_RT_EL3" +#if defined(SPD_opteed) +#define EVLOG_BL32_STRING "SECURE_RT_EL1_OPTEE" +#elif defined(SPD_tspd) +#define EVLOG_BL32_STRING "SECURE_RT_EL1_TSPD" +#elif defined(SPD_tlkd) +#define EVLOG_BL32_STRING "SECURE_RT_EL1_TLKD" +#elif defined(SPD_trusty) +#define EVLOG_BL32_STRING "SECURE_RT_EL1_TRUSTY" +#else +#define EVLOG_BL32_STRING "SECURE_RT_EL1_UNKNOWN" +#endif +#define EVLOG_BL32_EXTRA1_STRING "SECURE_RT_EL1_OPTEE_EXTRA1" +#define EVLOG_BL32_EXTRA2_STRING "SECURE_RT_EL1_OPTEE_EXTRA2" +#define EVLOG_BL33_STRING "BL_33" +#define EVLOG_FW_CONFIG_STRING "FW_CONFIG" +#define EVLOG_HW_CONFIG_STRING "HW_CONFIG" +#define EVLOG_NT_FW_CONFIG_STRING "NT_FW_CONFIG" +#define EVLOG_SCP_BL2_STRING "SYS_CTRL_2" +#define EVLOG_SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" +#define EVLOG_STM32_STRING "STM32" +#define EVLOG_TB_FW_CONFIG_STRING "TB_FW_CONFIG" +#define EVLOG_TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" typedef struct { unsigned int id; diff --git a/plat/arm/board/fvp/fvp_bl1_measured_boot.c b/plat/arm/board/fvp/fvp_bl1_measured_boot.c index 8815b74e4..47af1f554 100644 --- a/plat/arm/board/fvp/fvp_bl1_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl1_measured_boot.c @@ -14,9 +14,9 @@ static uint8_t event_log[PLAT_ARM_EVENT_LOG_MAX_SIZE]; /* FVP table with platform specific image IDs, names and PCRs */ const event_log_metadata_t fvp_event_log_metadata[] = { - { FW_CONFIG_ID, FW_CONFIG_STRING, PCR_0 }, - { TB_FW_CONFIG_ID, TB_FW_CONFIG_STRING, PCR_0 }, - { BL2_IMAGE_ID, BL2_STRING, PCR_0 }, + { FW_CONFIG_ID, EVLOG_FW_CONFIG_STRING, PCR_0 }, + { TB_FW_CONFIG_ID, EVLOG_TB_FW_CONFIG_STRING, PCR_0 }, + { BL2_IMAGE_ID, EVLOG_BL2_STRING, PCR_0 }, { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c index 16e8d79ee..5ebfedea0 100644 --- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -14,16 +14,16 @@ static uint64_t event_log_base; /* FVP table with platform specific image IDs, names and PCRs */ const event_log_metadata_t fvp_event_log_metadata[] = { - { BL31_IMAGE_ID, BL31_STRING, PCR_0 }, - { BL32_IMAGE_ID, BL32_STRING, PCR_0 }, - { BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, - { BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 }, - { BL33_IMAGE_ID, BL33_STRING, PCR_0 }, - { HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 }, - { NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 }, - { SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 }, - { SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 }, - { TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, + { BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 }, + { BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 }, + { BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 }, + { BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 }, + { BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 }, + { HW_CONFIG_ID, EVLOG_HW_CONFIG_STRING, PCR_0 }, + { NT_FW_CONFIG_ID, EVLOG_NT_FW_CONFIG_STRING, PCR_0 }, + { SCP_BL2_IMAGE_ID, EVLOG_SCP_BL2_STRING, PCR_0 }, + { SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 }, + { TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 }, { INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; -- cgit v1.2.3 From 9b3004cfbffbb79e030af4bc39a55231ded29e85 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 20 Sep 2021 15:19:59 +0100 Subject: docs(measured boot): add measured boot platform functions Signed-off-by: Manish V Badarkhe Change-Id: I411ee37cfeec32925849042689e8fdc7a26b7b13 --- docs/getting_started/porting-guide.rst | 91 ++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 54754fe6e..6569a4768 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1199,6 +1199,25 @@ This function returns SMC_ARCH_CALL_SUCCESS if the platform supports the SMCCC function specified in the argument; otherwise returns SMC_ARCH_CALL_NOT_SUPPORTED. +Function : plat_mboot_measure_image() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, image_info_t * + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function measures the given image and records its measurement using + the measured boot backend driver. +- On the Arm FVP port, this function measures the given image using its + passed id and information and then records that measurement in the + Event Log buffer. +- This function must return 0 on success, a negative error code otherwise. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + Modifications specific to a Boot Loader stage --------------------------------------------- @@ -1450,6 +1469,42 @@ This function must return 0 on success, a non-null error code otherwise. The default implementation of this function asserts therefore platforms must override it when using the FWU feature. +Function : bl1_plat_mboot_init() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to initialize the backend driver(s) of measured boot. +- On the Arm FVP port, this function is used to initialize the Event Log + backend driver, and also to write header information in the Event Log buffer. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : bl1_plat_mboot_finish() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to finalize the measured boot backend driver(s), + and also, set the information for the next bootloader component to + extend the measurement if needed. +- On the Arm FVP port, this function is used to pass the base address of + the Event Log buffer and its size to BL2 via tb_fw_config to extend the + Event Log buffer with the measurement of various images loaded by BL2. + It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + Boot Loader Stage 2 (BL2) ------------------------- @@ -1738,6 +1793,42 @@ Application Processor (AP) for BL2U execution to continue. This function returns 0 on success, a negative error code otherwise. This function is included if SCP_BL2U_BASE is defined. +Function : bl2_plat_mboot_init() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to initialize the backend driver(s) of measured boot. +- On the Arm FVP port, this function is used to initialize the Event Log + backend driver with the Event Log buffer information (base address and + size) received from BL1. It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : bl2_plat_mboot_finish() [optional] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : void + +When the MEASURED_BOOT flag is enabled: + +- This function is used to finalize the measured boot backend driver(s), + and also, set the information for the next bootloader component to extend + the measurement if needed. +- On the Arm FVP port, this function is used to pass the Event Log buffer + information (base address and size) to non-secure(BL33) and trusted OS(BL32) + via nt_fw and tos_fw config respectively. It results in panic on error. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + Boot Loader Stage 3-1 (BL31) ---------------------------- -- cgit v1.2.3 From b8a05116ed2a87a9689c4f9be6218a4bce88034a Mon Sep 17 00:00:00 2001 From: Shelley Chen Date: Fri, 1 Oct 2021 18:34:07 -0700 Subject: feat(plat/qti/sc7280): add support for pmk7325 The qti sc7280 platform uses the pmk7325 PMIC, which has the same functionality as the pm8998 driver, with the exception of the LC PON register offsets, which are defined as: Since it is nearly identical to the pm8998 driver, moving the above register offset definitions to platform_def.h for the respective SoC and reusing the rest of the functions defined in the pm8998 driver. Renaming pm8998 driver to pm_ps_hold to make it more generic. Change-Id: I0dda3a54579e0bbdd42c247405362a86d0607478 Signed-off-by: Shelley Chen --- plat/qti/common/src/pm8998.c | 43 -------------------------------------- plat/qti/common/src/pm_ps_hold.c | 41 ++++++++++++++++++++++++++++++++++++ plat/qti/sc7180/inc/platform_def.h | 5 +++++ plat/qti/sc7180/platform.mk | 2 +- plat/qti/sc7280/inc/platform_def.h | 5 +++++ plat/qti/sc7280/platform.mk | 2 +- 6 files changed, 53 insertions(+), 45 deletions(-) delete mode 100644 plat/qti/common/src/pm8998.c create mode 100644 plat/qti/common/src/pm_ps_hold.c diff --git a/plat/qti/common/src/pm8998.c b/plat/qti/common/src/pm8998.c deleted file mode 100644 index b189a8b86..000000000 --- a/plat/qti/common/src/pm8998.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020, Google LLC. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include -#include - -/* - * This driver implements PON support for PM8998-compatible PMICs. This can - * include other part numbers like PM6150. - */ - -#define PON_PS_HOLD_RESET_CTL 0x85a -#define RESET_TYPE_WARM_RESET 1 -#define RESET_TYPE_SHUTDOWN 4 - -#define PON_PS_HOLD_RESET_CTL2 0x85b -#define S2_RESET_EN BIT(7) - -static void configure_ps_hold(uint32_t reset_type) -{ - /* QTI recommends disabling reset for 10 cycles before reconfiguring. */ - spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0); - mdelay(1); - - spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type); - spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN); - mdelay(1); -} - -void qti_pmic_prepare_reset(void) -{ - configure_ps_hold(RESET_TYPE_WARM_RESET); -} - -void qti_pmic_prepare_shutdown(void) -{ - configure_ps_hold(RESET_TYPE_SHUTDOWN); -} diff --git a/plat/qti/common/src/pm_ps_hold.c b/plat/qti/common/src/pm_ps_hold.c new file mode 100644 index 000000000..208345cc1 --- /dev/null +++ b/plat/qti/common/src/pm_ps_hold.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020, Google LLC. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +/* + * This driver implements PON support for PM8998-compatible PMICs. This can + * include other part numbers like PM6150. + */ + +#define RESET_TYPE_WARM_RESET 1 +#define RESET_TYPE_SHUTDOWN 4 + +#define S2_RESET_EN BIT(7) + +static void configure_ps_hold(uint32_t reset_type) +{ + /* QTI recommends disabling reset for 10 cycles before reconfiguring. */ + spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, 0); + mdelay(1); + + spmi_arb_write8(PON_PS_HOLD_RESET_CTL, reset_type); + spmi_arb_write8(PON_PS_HOLD_RESET_CTL2, S2_RESET_EN); + mdelay(1); +} + +void qti_pmic_prepare_reset(void) +{ + configure_ps_hold(RESET_TYPE_WARM_RESET); +} + +void qti_pmic_prepare_shutdown(void) +{ + configure_ps_hold(RESET_TYPE_SHUTDOWN); +} diff --git a/plat/qti/sc7180/inc/platform_def.h b/plat/qti/sc7180/inc/platform_def.h index b0798a63f..e3dc81108 100644 --- a/plat/qti/sc7180/inc/platform_def.h +++ b/plat/qti/sc7180/inc/platform_def.h @@ -190,5 +190,10 @@ #define QTI_SOC_REVISION_REG 0x1FC8000 #define QTI_SOC_REVISION_MASK U(0xFFFF) /*----------------------------------------------------------------------------*/ +/* LC PON register offsets */ +/*----------------------------------------------------------------------------*/ +#define PON_PS_HOLD_RESET_CTL 0x85a +#define PON_PS_HOLD_RESET_CTL2 0x85b +/*----------------------------------------------------------------------------*/ #endif /* PLATFORM_DEF_H */ diff --git a/plat/qti/sc7180/platform.mk b/plat/qti/sc7180/platform.mk index ec560d036..141e2c39f 100644 --- a/plat/qti/sc7180/platform.mk +++ b/plat/qti/sc7180/platform.mk @@ -51,7 +51,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_silver.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo4_gold.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \ - $(QTI_PLAT_PATH)/common/src/pm8998.c \ + $(QTI_PLAT_PATH)/common/src/pm_ps_hold.c \ $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \ $(QTI_PLAT_PATH)/common/src/qti_common.c \ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \ diff --git a/plat/qti/sc7280/inc/platform_def.h b/plat/qti/sc7280/inc/platform_def.h index 660cb33a7..da7eddc7a 100644 --- a/plat/qti/sc7280/inc/platform_def.h +++ b/plat/qti/sc7280/inc/platform_def.h @@ -190,5 +190,10 @@ #define QTI_SOC_REVISION_REG 0x1FC8000 #define QTI_SOC_REVISION_MASK U(0xFFFF) /*----------------------------------------------------------------------------*/ +/* LC PON register offsets */ +/*----------------------------------------------------------------------------*/ +#define PON_PS_HOLD_RESET_CTL 0x852 +#define PON_PS_HOLD_RESET_CTL2 0x853 +/*----------------------------------------------------------------------------*/ #endif /* PLATFORM_DEF_H */ diff --git a/plat/qti/sc7280/platform.mk b/plat/qti/sc7280/platform.mk index 6e267816a..bc2c2210c 100644 --- a/plat/qti/sc7280/platform.mk +++ b/plat/qti/sc7280/platform.mk @@ -51,7 +51,7 @@ QTI_BL31_SOURCES := $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_helpers.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_silver.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_kryo6_gold.S \ $(QTI_PLAT_PATH)/common/src/$(ARCH)/qti_uart_console.S \ - $(QTI_PLAT_PATH)/common/src/pm8998.c \ + $(QTI_PLAT_PATH)/common/src/pm_ps_hold.c \ $(QTI_PLAT_PATH)/common/src/qti_stack_protector.c \ $(QTI_PLAT_PATH)/common/src/qti_common.c \ $(QTI_PLAT_PATH)/common/src/qti_bl31_setup.c \ -- cgit v1.2.3 From 71cb3a41ff3835f448afc261bf6395422249a0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 13 Oct 2021 11:37:12 +0200 Subject: build(plat/marvell): add descriptions why some checks are required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds just comments why some checks are required. They check that ENV variables and external repos are correctly set for TF-A builds. Signed-off-by: Pali Rohár Change-Id: I2f8af5061411c0c92d3875917f4d97b60dc2cf10 --- plat/marvell/armada/a3k/common/a3700_common.mk | 3 +++ plat/marvell/armada/a8k/common/ble/ble.mk | 1 + 2 files changed, 4 insertions(+) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index 955045221..c3f78c581 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -76,6 +76,7 @@ endif ifdef WTP +# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(wildcard $(value WTP)/*),,$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' directory does not exist")) $(if $(shell git -C $(value WTP) rev-parse --show-cdup 2>&1),$(error "'WTP=$(value WTP)' was specified, but '$(value WTP)' does not contain valid A3700-utils-marvell git repository")) @@ -143,6 +144,7 @@ CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH) CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH) $(TBB): FORCE + # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(CRYPTOPP_LIBDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_LIBDIR. Please set CRYPTOPP_PATH or CRYPTOPP_LIBDIR to point to the right directory")) $(if $(CRYPTOPP_INCDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_INCDIR. Please set CRYPTOPP_PATH or CRYPTOPP_INCDIR to point to the right directory")) $(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist")) @@ -159,6 +161,7 @@ $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG) $(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin $(TIMDDRTOOL): FORCE + # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) $(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist")) $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository")) diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk index 87e2ce020..e41ab3e2b 100644 --- a/plat/marvell/armada/a8k/common/ble/ble.mk +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -28,6 +28,7 @@ $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH) $(BLE_OBJS): $(MV_DDR_LIB) $(MV_DDR_LIB): FORCE + # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) $(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist")) $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository")) -- cgit v1.2.3 From 7d96e79a1a2efdf85f1ed46cdd5c577b58054f53 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Wed, 13 Oct 2021 13:29:06 +0100 Subject: fix(fvp_r): fix compilation error in release mode assert() is not used in release mode and complaining about unused variable "desc". Signed-off-by: Manish Pandey Change-Id: Ib919eb27532344a25be0b6ece7e239efa87be744 --- plat/arm/board/fvp_r/fvp_r_bl1_setup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c index 3f3fd5e9c..68872c111 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_setup.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_setup.c @@ -140,7 +140,6 @@ void plat_arm_secure_wdt_stop(void) */ void arm_bl1_platform_setup(void) { - image_desc_t *desc; uint32_t fw_config_max_size; /* Initialise the IO layer and register platform IO devices */ @@ -157,8 +156,7 @@ void arm_bl1_platform_setup(void) fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE; set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID); - desc = bl1_plat_get_image_desc(BL33_IMAGE_ID); - assert(desc != NULL); + assert(bl1_plat_get_image_desc(BL33_IMAGE_ID) != NULL); /* * Allow access to the System counter timer module and program -- cgit v1.2.3 From 125868c94150f52ff85cdb59aee623ab1f9f259d Mon Sep 17 00:00:00 2001 From: Nicola Mazzucato Date: Mon, 7 Jun 2021 22:53:27 +0100 Subject: fix(scmi): relax requirement for exact protocol version Currently, for the supported SCMI protocols, the version returned by the SCMI platform agent must be exactly matching the driver's version (major version). The recent change for the required version of Power Domain protocol means that the platform must return version 2.0. This can be however a limitation in some cases, where a SCMI-v1.0 platform can still be considered compatible with the driver supported in firmware. Relax the protocol version requirement such that any version older than the one supported by the drivers can still be compatible. Note: For now this has effect only on Power Domain protocol, as the other drivers still require the "base" version 1.0. Signed-off-by: Nicola Mazzucato Change-Id: I310ae1869c2e952991a8d733f394029ab64087bf --- include/drivers/arm/css/scmi.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/drivers/arm/css/scmi.h b/include/drivers/arm/css/scmi.h index adce7a62c..9dd08e5ab 100644 --- a/include/drivers/arm/css/scmi.h +++ b/include/drivers/arm/css/scmi.h @@ -25,10 +25,16 @@ #define MAKE_SCMI_VERSION(maj, min) \ ((((maj) & 0xffff) << 16) | ((min) & 0xffff)) -/* Macro to check if the driver is compatible with the SCMI version reported */ +/* + * Check that the driver's version is same or higher than the reported SCMI + * version. We accept lower major version numbers, as all affected protocols + * so far stay backwards compatible. This might need to be revisited in the + * future. + */ #define is_scmi_version_compatible(drv, scmi) \ + ((GET_SCMI_MAJOR_VER(drv) > GET_SCMI_MAJOR_VER(scmi)) || \ ((GET_SCMI_MAJOR_VER(drv) == GET_SCMI_MAJOR_VER(scmi)) && \ - (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi))) + (GET_SCMI_MINOR_VER(drv) <= GET_SCMI_MINOR_VER(scmi)))) /* SCMI Protocol identifiers */ #define SCMI_PWR_DMN_PROTO_ID 0x11 -- cgit v1.2.3 From c260b3246b6be27c7463d36ce7f76368c94a8540 Mon Sep 17 00:00:00 2001 From: Edward-JW Yang Date: Wed, 13 Oct 2021 19:57:33 +0800 Subject: feat(plat/mdeiatek/mt8195): remove adsp event from wakeup source Audio DSP is power-off when system suspend. Remove it from wakeup source list to prevent unnecessary wakeup. Signed-off-by: Edward-JW Yang Change-Id: Id7251de9c8b9c9a4a4b2c41a310168d336035b9a --- plat/mediatek/mt8195/drivers/spm/mt_spm_suspend.c | 1 - 1 file changed, 1 deletion(-) diff --git a/plat/mediatek/mt8195/drivers/spm/mt_spm_suspend.c b/plat/mediatek/mt8195/drivers/spm/mt_spm_suspend.c index b40fa873b..d01895321 100644 --- a/plat/mediatek/mt8195/drivers/spm/mt_spm_suspend.c +++ b/plat/mediatek/mt8195/drivers/spm/mt_spm_suspend.c @@ -46,7 +46,6 @@ R12_CCIF0_EVENT_B | \ R12_SSPM2SPM_WAKEUP_B | \ R12_SCP2SPM_WAKEUP_B | \ - R12_ADSP2SPM_WAKEUP_B | \ R12_USBX_CDSC_B | \ R12_USBX_POWERDWN_B | \ R12_SYS_TIMER_EVENT_B | \ -- cgit v1.2.3 From e5fbee5085c682ac3438e6f66c8bdaffb6076fa2 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 11 Oct 2021 19:46:08 +0100 Subject: fix(cc-713): fix a build failure with CC-713 library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed a below build failure with CC-713 library error: implicit declaration of function ‘mbedtls_x509_get_rsassa_pss_params’ [-Werror=implicit-function-declaration] Signed-off-by: Manish V Badarkhe Change-Id: If298ec16d133cf54413c299327b2c007ec4117b2 --- drivers/auth/cryptocell/713/cryptocell_crypto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/auth/cryptocell/713/cryptocell_crypto.c b/drivers/auth/cryptocell/713/cryptocell_crypto.c index 5f390a226..077317e7b 100644 --- a/drivers/auth/cryptocell/713/cryptocell_crypto.c +++ b/drivers/auth/cryptocell/713/cryptocell_crypto.c @@ -13,6 +13,7 @@ #include #include +#include #define LIB_NAME "CryptoCell 713 SBROM" #define RSA_SALT_LEN 32 -- cgit v1.2.3 From 10bfc77e7b3afce17185114ac66361a0914f7784 Mon Sep 17 00:00:00 2001 From: "Ying-Chun Liu (PaulLiu)" Date: Wed, 15 Sep 2021 21:13:13 +0800 Subject: fix(plat/imx/imx8m/imx8mm): fix FTBFS on SPD=opteed We need to add #include to platform_def.h to fix MODE_RW_64 undeclared. Signed-off-by: Ying-Chun Liu (PaulLiu) Change-Id: I358bc6644243a7ea1befd87f946b4087feddd857 --- plat/imx/imx8m/imx8mm/include/platform_def.h | 1 + 1 file changed, 1 insertion(+) diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index e86938bcc..6709678b2 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" -- cgit v1.2.3 From a1d5ac6a5aa5d9d18a481de20d272f64a71391f7 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 28 Apr 2021 17:52:02 -0500 Subject: feat(psci): require validate_power_state to expose CPU_SUSPEND psci_cpu_suspend unconditionally calls psci_validate_power_state, which asserts that the platform implements ops->validate_power_state. To avoid a failure at runtime, do not expose CPU_SUSPEND unless that callback is implemented. This also allows a platform to provide SYSTEM_SUSPEND without providing CPU_SUSPEND. Signed-off-by: Samuel Holland Change-Id: I5dafb7845f482ab3af03a9de562def41dd70189e --- lib/psci/psci_setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index 9c37d63f2..3cb4f7e43 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -250,7 +250,8 @@ int __init psci_setup(const psci_lib_args_t *lib_args) psci_caps |= define_psci_cap(PSCI_CPU_ON_AARCH64); if ((psci_plat_pm_ops->pwr_domain_suspend != NULL) && (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL)) { - psci_caps |= define_psci_cap(PSCI_CPU_SUSPEND_AARCH64); + if (psci_plat_pm_ops->validate_power_state != NULL) + psci_caps |= define_psci_cap(PSCI_CPU_SUSPEND_AARCH64); if (psci_plat_pm_ops->get_sys_suspend_power_state != NULL) psci_caps |= define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64); } -- cgit v1.2.3 From d68d163dd744aa35787bc3f8a9e987230fa576e9 Mon Sep 17 00:00:00 2001 From: Jorge Troncoso Date: Thu, 23 Sep 2021 17:14:29 -0700 Subject: refactor(ufs): reuse ufshc_send_uic_cmd This change aims to make the UFS code more robust by removing asserts and adding retry logic. We also reduce repetition by reusing ufshc_send_uic_cmd for DME_GET and DME_SET commands. Signed-off-by: Jorge Troncoso Change-Id: Id70aa1687d5ca78dc7d47234372255ac5a04a612 --- drivers/ufs/ufs.c | 60 ++++++++++++++++++++++++++++++--------------------- include/drivers/ufs.h | 4 ++++ 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 6dbf37236..97a9d5e7e 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -34,6 +34,9 @@ int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd) { unsigned int data; + if (base == 0 || cmd == NULL) + return -EINVAL; + data = mmio_read_32(base + HCS); if ((data & HCS_UCRDY) == 0) return -EBUSY; @@ -54,9 +57,13 @@ int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val) { uintptr_t base; unsigned int data; - int retries; + int result, retries; + uic_cmd_t cmd; - assert((ufs_params.reg_base != 0) && (val != NULL)); + assert(ufs_params.reg_base != 0); + + if (val == NULL) + return -EINVAL; base = ufs_params.reg_base; for (retries = 0; retries < 100; retries++) { @@ -68,19 +75,20 @@ int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val) if (retries >= 100) return -EBUSY; - mmio_write_32(base + IS, ~0); - mmio_write_32(base + UCMDARG1, (attr << 16) | GEN_SELECTOR_IDX(idx)); - mmio_write_32(base + UCMDARG2, 0); - mmio_write_32(base + UCMDARG3, 0); - mmio_write_32(base + UICCMD, DME_GET); - do { + cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx); + cmd.arg2 = 0; + cmd.arg3 = 0; + cmd.op = DME_GET; + for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) { + result = ufshc_send_uic_cmd(base, &cmd); + if (result == 0) + break; data = mmio_read_32(base + IS); if (data & UFS_INT_UE) return -EINVAL; - } while ((data & UFS_INT_UCCS) == 0); - mmio_write_32(base + IS, UFS_INT_UCCS); - data = mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK; - assert(data == 0); + } + if (retries >= UFS_UIC_COMMAND_RETRIES) + return -EIO; *val = mmio_read_32(base + UCMDARG3); return 0; @@ -90,26 +98,28 @@ int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val) { uintptr_t base; unsigned int data; + int result, retries; + uic_cmd_t cmd; assert((ufs_params.reg_base != 0)); base = ufs_params.reg_base; - data = mmio_read_32(base + HCS); - if ((data & HCS_UCRDY) == 0) - return -EBUSY; - mmio_write_32(base + IS, ~0); - mmio_write_32(base + UCMDARG1, (attr << 16) | GEN_SELECTOR_IDX(idx)); - mmio_write_32(base + UCMDARG2, 0); - mmio_write_32(base + UCMDARG3, val); - mmio_write_32(base + UICCMD, DME_SET); - do { + cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx); + cmd.arg2 = 0; + cmd.arg3 = val; + cmd.op = DME_SET; + + for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) { + result = ufshc_send_uic_cmd(base, &cmd); + if (result == 0) + break; data = mmio_read_32(base + IS); if (data & UFS_INT_UE) return -EINVAL; - } while ((data & UFS_INT_UCCS) == 0); - mmio_write_32(base + IS, UFS_INT_UCCS); - data = mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK; - assert(data == 0); + } + if (retries >= UFS_UIC_COMMAND_RETRIES) + return -EIO; + return 0; } diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h index 574c4ea0a..3f8f3605f 100644 --- a/include/drivers/ufs.h +++ b/include/drivers/ufs.h @@ -254,6 +254,10 @@ #define UFS_VENDOR_SKHYNIX U(0x1AD) #define MAX_MODEL_LEN 16 + +/* maximum number of retries for a general UIC command */ +#define UFS_UIC_COMMAND_RETRIES 3 + /** * ufs_dev_desc - ufs device details from the device descriptor * @wmanufacturerid: card details -- cgit v1.2.3 From 99ff1a35fe5e039097ba2520f00ecd862de6f6de Mon Sep 17 00:00:00 2001 From: Jorge Troncoso Date: Thu, 30 Sep 2021 16:29:32 -0700 Subject: refactor(ufs): add retry logic to ufshc_reset This change aims to make the UFS code more robust by adding retry logic and timeouts to ufshc_reset. We also define a new function ufshc_hce_enable for Host Controller Enable (HCE). The inner and outer retry pattern is based on Linux's ufshcd_hba_execute_hce function. Signed-off-by: Jorge Troncoso Change-Id: I9403a5a25d3ca50af5f2f9a65b774f6a2d7a9626 --- drivers/ufs/ufs.c | 38 ++++++++++++++++++++++++++++++++++---- include/drivers/ufs.h | 4 ++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 97a9d5e7e..695a614f2 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -123,21 +123,50 @@ int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val) return 0; } -static void ufshc_reset(uintptr_t base) +static int ufshc_hce_enable(uintptr_t base) { unsigned int data; + int retries; /* Enable Host Controller */ mmio_write_32(base + HCE, HCE_ENABLE); + /* Wait until basic initialization sequence completed */ - do { + for (retries = 0; retries < HCE_ENABLE_INNER_RETRIES; ++retries) { data = mmio_read_32(base + HCE); - } while ((data & HCE_ENABLE) == 0); + if (data & HCE_ENABLE) { + break; + } + udelay(HCE_ENABLE_TIMEOUT_US); + } + if (retries >= HCE_ENABLE_INNER_RETRIES) { + return -ETIMEDOUT; + } + + return 0; +} + +static int ufshc_reset(uintptr_t base) +{ + unsigned int data; + int retries, result; + + for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) { + result = ufshc_hce_enable(base); + if (result == 0) { + break; + } + } + if (retries >= HCE_ENABLE_OUTER_RETRIES) { + return -EIO; + } /* Enable Interrupts */ data = UFS_INT_UCCS | UFS_INT_ULSS | UFS_INT_UE | UFS_INT_UTPES | UFS_INT_DFES | UFS_INT_HCFES | UFS_INT_SBFES; mmio_write_32(base + IE, data); + + return 0; } static int ufshc_link_startup(uintptr_t base) @@ -782,7 +811,8 @@ int ufs_init(const ufs_ops_t *ops, ufs_params_t *params) assert((ops != NULL) && (ops->phy_init != NULL) && (ops->phy_set_pwr_mode != NULL)); - ufshc_reset(ufs_params.reg_base); + result = ufshc_reset(ufs_params.reg_base); + assert(result == 0); ops->phy_init(&ufs_params); result = ufshc_link_startup(ufs_params.reg_base); assert(result == 0); diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h index 3f8f3605f..686d4c6dc 100644 --- a/include/drivers/ufs.h +++ b/include/drivers/ufs.h @@ -258,6 +258,10 @@ /* maximum number of retries for a general UIC command */ #define UFS_UIC_COMMAND_RETRIES 3 +#define HCE_ENABLE_OUTER_RETRIES 3 +#define HCE_ENABLE_INNER_RETRIES 50 +#define HCE_ENABLE_TIMEOUT_US 100 + /** * ufs_dev_desc - ufs device details from the device descriptor * @wmanufacturerid: card details -- cgit v1.2.3 From 905635d5e74e3c7b7b2412a673009c8aaabb73e1 Mon Sep 17 00:00:00 2001 From: Jorge Troncoso Date: Tue, 5 Oct 2021 22:46:35 -0700 Subject: fix(ufs): add reset before DME_LINKSTARTUP This change aims to make the UFS code more robust by performing a controller reset if linkstartup fails. This idea was borrowed from Linux's ufshcd_link_startup function. Signed-off-by: Jorge Troncoso Change-Id: I6b52148d1bf155b11198dc82a39b1120057adaaf --- drivers/ufs/ufs.c | 24 ++++++++++++++++++------ include/drivers/ufs.h | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 695a614f2..ae42e326f 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -169,18 +169,30 @@ static int ufshc_reset(uintptr_t base) return 0; } -static int ufshc_link_startup(uintptr_t base) +static int ufshc_dme_link_startup(uintptr_t base) { uic_cmd_t cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.op = DME_LINKSTARTUP; + return ufshc_send_uic_cmd(base, &cmd); +} + +static int ufshc_link_startup(uintptr_t base) +{ int data, result; int retries; - for (retries = 10; retries > 0; retries--) { - memset(&cmd, 0, sizeof(cmd)); - cmd.op = DME_LINKSTARTUP; - result = ufshc_send_uic_cmd(base, &cmd); - if (result != 0) + for (retries = DME_LINKSTARTUP_RETRIES; retries > 0; retries--) { + result = ufshc_dme_link_startup(base); + if (result != 0) { + /* Reset controller before trying again */ + result = ufshc_reset(base); + if (result != 0) { + return result; + } continue; + } while ((mmio_read_32(base + HCS) & HCS_DP) == 0) ; data = mmio_read_32(base + IS); diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h index 686d4c6dc..c074e85d1 100644 --- a/include/drivers/ufs.h +++ b/include/drivers/ufs.h @@ -258,6 +258,9 @@ /* maximum number of retries for a general UIC command */ #define UFS_UIC_COMMAND_RETRIES 3 +/* maximum number of link-startup retries */ +#define DME_LINKSTARTUP_RETRIES 10 + #define HCE_ENABLE_OUTER_RETRIES 3 #define HCE_ENABLE_INNER_RETRIES 50 #define HCE_ENABLE_TIMEOUT_US 100 -- cgit v1.2.3 From d2ece8dba2f31091b1fa6c302d4255495bb15705 Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:34:34 +0900 Subject: fix(plat/rcar): fix to load image when option BL2_DCACHE_ENABLE is enabled - Modify load destination variable of the Cert Header to static. - Modify the return value to error (IO_FAIL) when failed to check the Cert Header. Signed-off-by: Koichi Yamaguchi Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: Ief09a841ec8d2ae236de82d04855e6a47cfb43f0 --- drivers/renesas/common/io/io_rcar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c index 17d7aaa29..fa7b958e0 100644 --- a/drivers/renesas/common/io/io_rcar.c +++ b/drivers/renesas/common/io/io_rcar.c @@ -380,7 +380,7 @@ static int32_t load_bl33x(void) static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) { - uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL}; + static uint64_t header[64] __aligned(FLASH_TRANS_SIZE_UNIT) = {0UL}; uintptr_t handle; ssize_t offset; uint32_t i; @@ -440,6 +440,7 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) if (rcar_image_number == 0 || rcar_image_number > RCAR_MAX_BL3X_IMAGE) { WARN("Firmware Image Package header check failed.\n"); + rc = IO_FAIL; goto error; } -- cgit v1.2.3 From c77ab18ec7c8e0f3d953177b835e004a9b53515f Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Tue, 13 Jul 2021 14:20:57 +0900 Subject: fix(plat/rcar): fix cache maintenance process of reading cert header Move calling inv_dcache_range from before io_read to after that. Signed-off-by: Hideyuki Nitta Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: Ic0dabf3eb94eeeb04099ed5127cdfda79bbac9b3 --- drivers/renesas/common/io/io_rcar.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c index fa7b958e0..45ef386ae 100644 --- a/drivers/renesas/common/io/io_rcar.c +++ b/drivers/renesas/common/io/io_rcar.c @@ -423,15 +423,17 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) WARN("Firmware Image Package header failed to seek\n"); goto error; } -#if RCAR_BL2_DCACHE == 1 - inv_dcache_range((uint64_t) header, sizeof(header)); -#endif + rc = io_read(handle, (uintptr_t) &header, sizeof(header), &cnt); if (rc != IO_SUCCESS) { WARN("Firmware Image Package header failed to read\n"); goto error; } +#if RCAR_BL2_DCACHE == 1 + inv_dcache_range((uint64_t) header, sizeof(header)); +#endif + rcar_image_number = header[0]; for (i = 0; i < rcar_image_number + 2; i++) { rcar_image_header[i] = header[i * 2 + 1]; @@ -449,10 +451,7 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) WARN("Firmware Image Package header failed to seek cert\n"); goto error; } -#if RCAR_BL2_DCACHE == 1 - inv_dcache_range(RCAR_SDRAM_certESS, - RCAR_CERT_SIZE * (2 + rcar_image_number)); -#endif + rc = io_read(handle, RCAR_SDRAM_certESS, RCAR_CERT_SIZE * (2 + rcar_image_number), &cnt); if (rc != IO_SUCCESS) { @@ -460,6 +459,11 @@ static int32_t rcar_dev_init(io_dev_info_t *dev_info, const uintptr_t name) goto error; } +#if RCAR_BL2_DCACHE == 1 + inv_dcache_range(RCAR_SDRAM_certESS, + RCAR_CERT_SIZE * (2 + rcar_image_number)); +#endif + rcar_cert_load = RCAR_CERT_LOAD; error: -- cgit v1.2.3 From 49593cc1ce0d0471aeef7ca24a5415da2dd55bea Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:04:01 +0900 Subject: fix(plat/rcar): change process that copy code to system ram Change processing of invalidate instruction cache to after changing the RAM attribute. Signed-off-by: Koichi Yamaguchi Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Signed-off-by: Marek Vasut # squash with rcar_gen3: drivers: Disable data cache while Suspend To RAM Change-Id: I61339fc5415b26074b1e0753da4c4a432e8f83d9 --- drivers/renesas/common/pwrc/pwrc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/renesas/common/pwrc/pwrc.c b/drivers/renesas/common/pwrc/pwrc.c index 4ebf04906..4e175eb97 100644 --- a/drivers/renesas/common/pwrc/pwrc.c +++ b/drivers/renesas/common/pwrc/pwrc.c @@ -776,14 +776,14 @@ void rcar_pwrc_code_copy_to_system_ram(void) memcpy((void *)sram.base, code.base, code.len); flush_dcache_range((uint64_t) sram.base, code.len); + attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE; + ret = xlat_change_mem_attributes(sram.base, sram.len, attr); + assert(ret == 0); + /* Invalidate instruction cache */ plat_invalidate_icache(); dsb(); isb(); - - attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE; - ret = xlat_change_mem_attributes(sram.base, sram.len, attr); - assert(ret == 0); } uint32_t rcar_pwrc_get_cluster(void) -- cgit v1.2.3 From 731aa26f38d76645b6d50077c28dffb9b02dd08a Mon Sep 17 00:00:00 2001 From: Toshiyuki Ogasahara Date: Mon, 12 Jul 2021 19:29:52 +0900 Subject: feat(plat/rcar): change process for Suspend To RAM - Added the function rcar_pwr_domain_pwr_down_wfi() for power down process. And change the sequence to power down. - Removed clearing the count of psci_locks (PSCI exclusive lock) during Warm Boot. Signed-off-by: Koichi Yamaguchi Signed-off-by: Toshiyuki Ogasahara Signed-off-by: Yoshifumi Hosoya Change-Id: I684d54a798a6dccde15fbebe16c6e104cbb470ed --- plat/renesas/common/plat_pm.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/plat/renesas/common/plat_pm.c b/plat/renesas/common/plat_pm.c index 6a9ad450d..1d4a7f634 100644 --- a/plat/renesas/common/plat_pm.c +++ b/plat/renesas/common/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -128,11 +128,6 @@ static void rcar_pwr_domain_suspend(const psci_power_state_t *target_state) rcar_pwrc_clusteroff(mpidr); } - -#if RCAR_SYSTEM_SUSPEND - if (SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) - rcar_pwrc_suspend_to_ram(); -#endif } static void rcar_pwr_domain_suspend_finish(const psci_power_state_t @@ -160,6 +155,18 @@ finish: rcar_pwr_domain_on_finish(target_state); } +static void __dead2 rcar_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ +#if RCAR_SYSTEM_SUSPEND + if (SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) + rcar_pwrc_suspend_to_ram(); +#endif + wfi(); + + ERROR("RCAR Power Down: operation not handled.\n"); + panic(); +} + static void __dead2 rcar_system_off(void) { #if PMIC_ROHM_BD9571 @@ -292,6 +299,7 @@ static const plat_psci_ops_t rcar_plat_psci_ops = { .system_off = rcar_system_off, .system_reset = rcar_system_reset, .validate_power_state = rcar_validate_power_state, + .pwr_domain_pwr_down_wfi = rcar_pwr_domain_pwr_down_wfi, #if RCAR_SYSTEM_SUSPEND .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state, #endif -- cgit v1.2.3 From e0baae7316bfdf3e49e5e158f79eb80cd51fc700 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 14 Oct 2021 10:36:46 +0100 Subject: fix(scmi): mention "SCMI" in driver initialisation message Currently the SCMI driver reports: INFO: Initializing driver on Channel 0 on the console, which is not very specific (which driver?). Add "SCMI" to the message so the user knows what the firmware is trying to initialise. Change-Id: Id8202655d07b8e12fe07670d462c6202e6eae2f0 Signed-off-by: Andre Przywara --- drivers/arm/css/scp/css_pm_scmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c index aeb7eda30..5de2604cb 100644 --- a/drivers/arm/css/scp/css_pm_scmi.c +++ b/drivers/arm/css/scp/css_pm_scmi.c @@ -357,7 +357,7 @@ void __init plat_arm_pwrc_setup(void) unsigned int composite_id, idx; for (idx = 0; idx < PLAT_ARM_SCMI_CHANNEL_COUNT; idx++) { - INFO("Initializing driver on Channel %d\n", idx); + INFO("Initializing SCMI driver on channel %d\n", idx); scmi_channels[idx].info = plat_css_get_scmi_info(idx); scmi_channels[idx].lock = ARM_SCMI_LOCK_GET_INSTANCE; -- cgit v1.2.3 From 7b81471f919fe8c8f1a4173bca12ac72a9f25591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Tue, 19 Oct 2021 16:10:29 +0200 Subject: build(plat/marvell): do not print comments on stdout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit '#' needs to be before TAB, otherwise comment is printed on stdout during build. Signed-off-by: Pali Rohár Change-Id: I502374ef35d91e194dc35b78d31d6884a466fab2 --- plat/marvell/armada/a3k/common/a3700_common.mk | 4 ++-- plat/marvell/armada/a8k/common/ble/ble.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/marvell/armada/a3k/common/a3700_common.mk b/plat/marvell/armada/a3k/common/a3700_common.mk index c3f78c581..d0e86886a 100644 --- a/plat/marvell/armada/a3k/common/a3700_common.mk +++ b/plat/marvell/armada/a3k/common/a3700_common.mk @@ -144,7 +144,7 @@ CRYPTOPP_LIBDIR ?= $(CRYPTOPP_PATH) CRYPTOPP_INCDIR ?= $(CRYPTOPP_PATH) $(TBB): FORCE - # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds +# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(CRYPTOPP_LIBDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_LIBDIR. Please set CRYPTOPP_PATH or CRYPTOPP_LIBDIR to point to the right directory")) $(if $(CRYPTOPP_INCDIR),,$(error "Platform '$(PLAT)' for WTP image tool requires CRYPTOPP_PATH or CRYPTOPP_INCDIR. Please set CRYPTOPP_PATH or CRYPTOPP_INCDIR to point to the right directory")) $(if $(wildcard $(CRYPTOPP_LIBDIR)/*),,$(error "Either 'CRYPTOPP_PATH' or 'CRYPTOPP_LIB' was set to '$(CRYPTOPP_LIBDIR)', but '$(CRYPTOPP_LIBDIR)' does not exist")) @@ -161,7 +161,7 @@ $(BUILD_PLAT)/wtmi.bin: $(WTMI_MULTI_IMG) $(Q)cp -a $(WTMI_MULTI_IMG) $(BUILD_PLAT)/wtmi.bin $(TIMDDRTOOL): FORCE - # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds +# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(value MV_DDR_PATH),,$(error "Platform '${PLAT}' for ddr tool requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) $(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist")) $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository")) diff --git a/plat/marvell/armada/a8k/common/ble/ble.mk b/plat/marvell/armada/a8k/common/ble/ble.mk index e41ab3e2b..160e98f12 100644 --- a/plat/marvell/armada/a8k/common/ble/ble.mk +++ b/plat/marvell/armada/a8k/common/ble/ble.mk @@ -28,7 +28,7 @@ $(BLE_OBJS): PLAT_INCLUDES += -I$(MV_DDR_PATH) $(BLE_OBJS): $(MV_DDR_LIB) $(MV_DDR_LIB): FORCE - # Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds +# Do not remove! Following checks are required to ensure correct TF-A builds, removing these checks leads to broken TF-A builds $(if $(value MV_DDR_PATH),,$(error "Platform '$(PLAT)' for BLE requires MV_DDR_PATH. Please set MV_DDR_PATH to point to the right directory")) $(if $(wildcard $(value MV_DDR_PATH)/*),,$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' directory does not exist")) $(if $(shell git -C $(value MV_DDR_PATH) rev-parse --show-cdup 2>&1),$(error "'MV_DDR_PATH=$(value MV_DDR_PATH)' was specified, but '$(value MV_DDR_PATH)' does not contain valid mv-ddr-marvell git repository")) -- cgit v1.2.3 From 596d20d9e4d50c02b5a0cce8cad2a1c205cd687a Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Fri, 15 Oct 2021 17:25:52 -0500 Subject: fix(pie): invalidate data cache in the entire image range if PIE is enabled Currently on image entry, the data cache in the RW address range is invalidated before MMU is enabled to safeguard against potential stale data from previous firmware stage. If PIE is enabled however, RO sections including the GOT may be also modified during pie fixup. Therefore, to be on the safe side, invalidate the entire image region if PIE is enabled. Signed-off-by: Zelalem Aweke Change-Id: I7ee2a324fe4377b026e32f9ab842617ad4e09d89 --- bl32/tsp/aarch64/tsp_entrypoint.S | 22 +++++++++++++++++++--- include/arch/aarch32/el3_common_macros.S | 13 ++++++++++++- include/arch/aarch64/el3_common_macros.S | 15 ++++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/bl32/tsp/aarch64/tsp_entrypoint.S b/bl32/tsp/aarch64/tsp_entrypoint.S index 795c5865e..7d77f478b 100644 --- a/bl32/tsp/aarch64/tsp_entrypoint.S +++ b/bl32/tsp/aarch64/tsp_entrypoint.S @@ -100,11 +100,27 @@ func tsp_entrypoint _align=3 * sections. This is done to safeguard against * possible corruption of this memory by dirty * cache lines in a system cache as a result of - * use by an earlier boot loader stage. + * use by an earlier boot loader stage. If PIE + * is enabled however, RO sections including the + * GOT may be modified during pie fixup. + * Therefore, to be on the safe side, invalidate + * the entire image region if PIE is enabled. * --------------------------------------------- */ - adr x0, __RW_START__ - adr x1, __RW_END__ +#if ENABLE_PIE +#if SEPARATE_CODE_AND_RODATA + adrp x0, __TEXT_START__ + add x0, x0, :lo12:__TEXT_START__ +#else + adrp x0, __RO_START__ + add x0, x0, :lo12:__RO_START__ +#endif /* SEPARATE_CODE_AND_RODATA */ +#else + adrp x0, __RW_START__ + add x0, x0, :lo12:__RW_START__ +#endif /* ENABLE_PIE */ + adrp x1, __RW_END__ + add x1, x1, :lo12:__RW_END__ sub x1, x1, x0 bl inv_dcache_range diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 65f9a8e6b..ad2a03911 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -380,10 +380,21 @@ * includes the data and NOBITS sections. This is done to * safeguard against possible corruption of this memory by * dirty cache lines in a system cache as a result of use by - * an earlier boot loader stage. + * an earlier boot loader stage. If PIE is enabled however, + * RO sections including the GOT may be modified during + * pie fixup. Therefore, to be on the safe side, invalidate + * the entire image region if PIE is enabled. * ----------------------------------------------------------------- */ +#if ENABLE_PIE +#if SEPARATE_CODE_AND_RODATA + ldr r0, =__TEXT_START__ +#else + ldr r0, =__RO_START__ +#endif /* SEPARATE_CODE_AND_RODATA */ +#else ldr r0, =__RW_START__ +#endif /* ENABLE_PIE */ ldr r1, =__RW_END__ sub r1, r1, r0 bl inv_dcache_range diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 7d6a9638d..8e8d33480 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -430,11 +430,24 @@ * includes the data and NOBITS sections. This is done to * safeguard against possible corruption of this memory by * dirty cache lines in a system cache as a result of use by - * an earlier boot loader stage. + * an earlier boot loader stage. If PIE is enabled however, + * RO sections including the GOT may be modified during + * pie fixup. Therefore, to be on the safe side, invalidate + * the entire image region if PIE is enabled. * ------------------------------------------------------------- */ +#if ENABLE_PIE +#if SEPARATE_CODE_AND_RODATA + adrp x0, __TEXT_START__ + add x0, x0, :lo12:__TEXT_START__ +#else + adrp x0, __RO_START__ + add x0, x0, :lo12:__RO_START__ +#endif /* SEPARATE_CODE_AND_RODATA */ +#else adrp x0, __RW_START__ add x0, x0, :lo12:__RW_START__ +#endif /* ENABLE_PIE */ adrp x1, __RW_END__ add x1, x1, :lo12:__RW_END__ sub x1, x1, x0 -- cgit v1.2.3 From fb9e5f7bb76e9764b3ecd7973668c851015fa1b4 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 19 Aug 2021 16:51:26 -0500 Subject: feat(cpu): add support for Hunter CPU This patch adds the basic CPU library code to support the Hunter CPU in TF-A. This CPU is based on the Makalu core so that library code was adapted as the basis for this patch. Signed-off-by: John Powell Change-Id: I956b2dc0f43da7cec3e015252392e2694363e1b3 --- include/lib/cpus/aarch64/cortex_hunter.h | 23 ++++++++++ lib/cpus/aarch64/cortex_hunter.S | 77 ++++++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 include/lib/cpus/aarch64/cortex_hunter.h create mode 100644 lib/cpus/aarch64/cortex_hunter.S diff --git a/include/lib/cpus/aarch64/cortex_hunter.h b/include/lib/cpus/aarch64/cortex_hunter.h new file mode 100644 index 000000000..8b59fd9ea --- /dev/null +++ b/include/lib/cpus/aarch64/cortex_hunter.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CORTEX_HUNTER_H +#define CORTEX_HUNTER_H + +#define CORTEX_HUNTER_MIDR U(0x410FD810) + +/******************************************************************************* + * CPU Extended Control register specific definitions + ******************************************************************************/ +#define CORTEX_HUNTER_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define CORTEX_HUNTER_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define CORTEX_HUNTER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* CORTEX_HUNTER_H */ diff --git a/lib/cpus/aarch64/cortex_hunter.S b/lib/cpus/aarch64/cortex_hunter.S new file mode 100644 index 000000000..2ab429615 --- /dev/null +++ b/lib/cpus/aarch64/cortex_hunter.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* Hardware handled coherency */ +#if HW_ASSISTED_COHERENCY == 0 +#error "Cortex Hunter must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex Hunter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + +func cortex_hunter_reset_func + /* Disable speculative loads */ + msr SSBS, xzr + isb + ret +endfunc cortex_hunter_reset_func + + /* ---------------------------------------------------- + * HW will do the cache maintenance while powering down + * ---------------------------------------------------- + */ +func cortex_hunter_core_pwr_dwn + /* --------------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------------- + */ + mrs x0, CORTEX_HUNTER_CPUPWRCTLR_EL1 + orr x0, x0, #CORTEX_HUNTER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr CORTEX_HUNTER_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc cortex_hunter_core_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Cortex Hunter. Must follow AAPCS. + */ +func cortex_hunter_errata_report + ret +endfunc cortex_hunter_errata_report +#endif + + /* --------------------------------------------- + * This function provides Cortex Hunter-specific + * register information for crash reporting. + * It needs to return with x6 pointing to + * a list of register names in ascii and + * x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.cortex_hunter_regs, "aS" +cortex_hunter_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func cortex_hunter_cpu_reg_dump + adr x6, cortex_hunter_regs + mrs x8, CORTEX_HUNTER_CPUECTLR_EL1 + ret +endfunc cortex_hunter_cpu_reg_dump + +declare_cpu_ops cortex_hunter, CORTEX_HUNTER_MIDR, \ + cortex_hunter_reset_func, \ + cortex_hunter_core_pwr_dwn diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 70b1051a8..0d0d1a67b 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -139,7 +139,8 @@ else lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S \ lib/cpus/aarch64/cortex_a78c.S \ - lib/cpus/aarch64/cortex_hayes.S + lib/cpus/aarch64/cortex_hayes.S \ + lib/cpus/aarch64/cortex_hunter.S endif # AArch64/AArch32 cores FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ -- cgit v1.2.3 From 403f4cb3e744b3893195e69af176cb3b4c113248 Mon Sep 17 00:00:00 2001 From: Daniel Boulby Date: Mon, 18 Oct 2021 09:48:30 +0100 Subject: docs(gcc): update GCC to version 10.3-2021.07 This toolchain provides multiple cross compilers and is publicly available on developer.arm.com We build TF-A in CI using: AArch32 bare-metal target (arm-none-eabi) AArch64 ELF bare-metal target (aarch64-none-elf) Change-Id: I673e0dce8eb3ca3a004a43158a948431b032e93a Signed-off-by: Daniel Boulby --- docs/getting_started/prerequisites.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst index aa1ae67d1..f45193ae2 100644 --- a/docs/getting_started/prerequisites.rst +++ b/docs/getting_started/prerequisites.rst @@ -26,7 +26,7 @@ Toolchain |TF-A| can be built with any of the following *cross-compiler* toolchains that target the Armv7-A or Armv8-A architectures: -- GCC >= 10.2-2020.11 (from the `Arm Developer website`_) +- GCC >= 10.3-2021.07 (from the `Arm Developer website`_) - Clang >= 4.0 - Arm Compiler >= 6.0 -- cgit v1.2.3 From 500888511da9ec0c61fa0ee25e0c4f0023cb7a2c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Thu, 21 Oct 2021 14:57:52 +0200 Subject: docs(stm32mp1): fix FIP command with OP-TEE When building a FIP with OP-TEE as BL32 on STM32MP1, AARCH32_SP=optee has to be added to the make command. Change-Id: I900c01957fe4ed7ed13ca955edd91ed1c5c5c4fa Signed-off-by: Yann Gautier --- docs/plat/stm32mp1.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst index 17f7a8618..af302c628 100644 --- a/docs/plat/stm32mp1.rst +++ b/docs/plat/stm32mp1.rst @@ -181,6 +181,7 @@ With OP-TEE: .. code:: bash make CROSS_COMPILE=arm-none-eabi- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 \ + AARCH32_SP=optee \ DTB_FILE_NAME=stm32mp157c-ev1.dtb \ BL33=/u-boot-nodtb.bin \ BL33_CFG=/u-boot.dtb \ -- cgit v1.2.3 From 4cb576a0c5bd2e7669606996a9f79602596df07c Mon Sep 17 00:00:00 2001 From: johpow01 Date: Fri, 15 Oct 2021 12:02:36 -0500 Subject: fix(cpu): correct Demeter CPU name This patch changes Cortex Demeter to Neoverse Demeter. Signed-off-by: John Powell Change-Id: I7306d09ca60e101d0a96c9ceff9845422d75c160 --- include/lib/cpus/aarch64/cortex_demeter.h | 23 --------- include/lib/cpus/aarch64/neoverse_demeter.h | 23 +++++++++ lib/cpus/aarch64/cortex_demeter.S | 77 ----------------------------- lib/cpus/aarch64/neoverse_demeter.S | 77 +++++++++++++++++++++++++++++ plat/arm/board/fvp/platform.mk | 2 +- 5 files changed, 101 insertions(+), 101 deletions(-) delete mode 100644 include/lib/cpus/aarch64/cortex_demeter.h create mode 100644 include/lib/cpus/aarch64/neoverse_demeter.h delete mode 100644 lib/cpus/aarch64/cortex_demeter.S create mode 100644 lib/cpus/aarch64/neoverse_demeter.S diff --git a/include/lib/cpus/aarch64/cortex_demeter.h b/include/lib/cpus/aarch64/cortex_demeter.h deleted file mode 100644 index 9dd0987ab..000000000 --- a/include/lib/cpus/aarch64/cortex_demeter.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef CORTEX_DEMETER_H -#define CORTEX_DEMETER_H - -#define CORTEX_DEMETER_MIDR U(0x410FD4F0) - -/******************************************************************************* - * CPU Extended Control register specific definitions - ******************************************************************************/ -#define CORTEX_DEMETER_CPUECTLR_EL1 S3_0_C15_C1_4 - -/******************************************************************************* - * CPU Power Control register specific definitions - ******************************************************************************/ -#define CORTEX_DEMETER_CPUPWRCTLR_EL1 S3_0_C15_C2_7 -#define CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) - -#endif /* CORTEX_DEMETER_H */ diff --git a/include/lib/cpus/aarch64/neoverse_demeter.h b/include/lib/cpus/aarch64/neoverse_demeter.h new file mode 100644 index 000000000..230ed6651 --- /dev/null +++ b/include/lib/cpus/aarch64/neoverse_demeter.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef NEOVERSE_DEMETER_H +#define NEOVERSE_DEMETER_H + +#define NEOVERSE_DEMETER_MIDR U(0x410FD4F0) + +/******************************************************************************* + * CPU Extended Control register specific definitions + ******************************************************************************/ +#define NEOVERSE_DEMETER_CPUECTLR_EL1 S3_0_C15_C1_4 + +/******************************************************************************* + * CPU Power Control register specific definitions + ******************************************************************************/ +#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1 S3_0_C15_C2_7 +#define NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT U(1) + +#endif /* NEOVERSE_DEMETER_H */ diff --git a/lib/cpus/aarch64/cortex_demeter.S b/lib/cpus/aarch64/cortex_demeter.S deleted file mode 100644 index 9ad8b86fd..000000000 --- a/lib/cpus/aarch64/cortex_demeter.S +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -/* Hardware handled coherency */ -#if HW_ASSISTED_COHERENCY == 0 -#error "Cortex Demeter must be compiled with HW_ASSISTED_COHERENCY enabled" -#endif - -/* 64-bit only core */ -#if CTX_INCLUDE_AARCH32_REGS == 1 -#error "Cortex Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" -#endif - - /* ---------------------------------------------------- - * HW will do the cache maintenance while powering down - * ---------------------------------------------------- - */ -func cortex_demeter_core_pwr_dwn - /* --------------------------------------------------- - * Enable CPU power down bit in power control register - * --------------------------------------------------- - */ - mrs x0, CORTEX_DEMETER_CPUPWRCTLR_EL1 - orr x0, x0, #CORTEX_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT - msr CORTEX_DEMETER_CPUPWRCTLR_EL1, x0 - isb - ret -endfunc cortex_demeter_core_pwr_dwn - -#if REPORT_ERRATA -/* - * Errata printing function for Cortex Demeter. Must follow AAPCS. - */ -func cortex_demeter_errata_report - ret -endfunc cortex_demeter_errata_report -#endif - -func cortex_demeter_reset_func - /* Disable speculative loads */ - msr SSBS, xzr - isb - ret -endfunc cortex_demeter_reset_func - - /* --------------------------------------------- - * This function provides Cortex Demeter- - * specific register information for crash - * reporting. It needs to return with x6 - * pointing to a list of register names in ascii - * and x8 - x15 having values of registers to be - * reported. - * --------------------------------------------- - */ -.section .rodata.cortex_demeter_regs, "aS" -cortex_demeter_regs: /* The ascii list of register names to be reported */ - .asciz "cpuectlr_el1", "" - -func cortex_demeter_cpu_reg_dump - adr x6, cortex_demeter_regs - mrs x8, CORTEX_DEMETER_CPUECTLR_EL1 - ret -endfunc cortex_demeter_cpu_reg_dump - -declare_cpu_ops cortex_demeter, CORTEX_DEMETER_MIDR, \ - cortex_demeter_reset_func, \ - cortex_demeter_core_pwr_dwn diff --git a/lib/cpus/aarch64/neoverse_demeter.S b/lib/cpus/aarch64/neoverse_demeter.S new file mode 100644 index 000000000..f43c18b6b --- /dev/null +++ b/lib/cpus/aarch64/neoverse_demeter.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include + +/* Hardware handled coherency */ +#if HW_ASSISTED_COHERENCY == 0 +#error "Neoverse Demeter must be compiled with HW_ASSISTED_COHERENCY enabled" +#endif + +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse Demeter supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + + /* ---------------------------------------------------- + * HW will do the cache maintenance while powering down + * ---------------------------------------------------- + */ +func neoverse_demeter_core_pwr_dwn + /* --------------------------------------------------- + * Enable CPU power down bit in power control register + * --------------------------------------------------- + */ + mrs x0, NEOVERSE_DEMETER_CPUPWRCTLR_EL1 + orr x0, x0, #NEOVERSE_DEMETER_CPUPWRCTLR_EL1_CORE_PWRDN_BIT + msr NEOVERSE_DEMETER_CPUPWRCTLR_EL1, x0 + isb + ret +endfunc neoverse_demeter_core_pwr_dwn + +#if REPORT_ERRATA +/* + * Errata printing function for Neoverse Demeter. Must follow AAPCS. + */ +func neoverse_demeter_errata_report + ret +endfunc neoverse_demeter_errata_report +#endif + +func neoverse_demeter_reset_func + /* Disable speculative loads */ + msr SSBS, xzr + isb + ret +endfunc neoverse_demeter_reset_func + + /* --------------------------------------------- + * This function provides Neoverse Demeter- + * specific register information for crash + * reporting. It needs to return with x6 + * pointing to a list of register names in ascii + * and x8 - x15 having values of registers to be + * reported. + * --------------------------------------------- + */ +.section .rodata.neoverse_demeter_regs, "aS" +neoverse_demeter_regs: /* The ascii list of register names to be reported */ + .asciz "cpuectlr_el1", "" + +func neoverse_demeter_cpu_reg_dump + adr x6, neoverse_demeter_regs + mrs x8, NEOVERSE_DEMETER_CPUECTLR_EL1 + ret +endfunc neoverse_demeter_cpu_reg_dump + +declare_cpu_ops neoverse_demeter, NEOVERSE_DEMETER_MIDR, \ + neoverse_demeter_reset_func, \ + neoverse_demeter_core_pwr_dwn diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 0d0d1a67b..fd27acb58 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -130,12 +130,12 @@ else lib/cpus/aarch64/neoverse_n2.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_v1.S \ + lib/cpus/aarch64/neoverse_demeter.S \ lib/cpus/aarch64/cortex_a78_ae.S \ lib/cpus/aarch64/cortex_a510.S \ lib/cpus/aarch64/cortex_a710.S \ lib/cpus/aarch64/cortex_makalu.S \ lib/cpus/aarch64/cortex_makalu_elp_arm.S \ - lib/cpus/aarch64/cortex_demeter.S \ lib/cpus/aarch64/cortex_a65.S \ lib/cpus/aarch64/cortex_a65ae.S \ lib/cpus/aarch64/cortex_a78c.S \ -- cgit v1.2.3 From 700e7685dd4682a929645a79de39f503c9140b2d Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Thu, 21 Oct 2021 21:53:49 +0100 Subject: fix: remove "experimental" tag for stable features there are features which are marked as experimental even though they are stable and used for quite some time. Following features are no longer marked as experimental - SPMD - MEASURED_BOOT - FCONF and associated build flags - DECRYPTION_SUPPORT and associated build flags - ENABLE_PAUTH - ENABLE_BTI - USE_SPINLOCK_CAS - GICv3 Multichip support Signed-off-by: Manish Pandey Change-Id: I4bb653d9c413c66095ec31f0b8aefeb13ea04ee9 --- Makefile | 26 +------------------------- docs/about/features.rst | 6 ++---- docs/design/firmware-design.rst | 5 +---- docs/design/trusted-board-boot.rst | 3 --- docs/getting_started/build-options.rst | 31 +++++++++++++------------------ docs/getting_started/porting-guide.rst | 3 +-- drivers/arm/gic/v3/gic600_multichip.c | 4 ---- 7 files changed, 18 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index ec6f88585..c4e2ee3de 100644 --- a/Makefile +++ b/Makefile @@ -150,8 +150,6 @@ endif ifeq (${USE_SPINLOCK_CAS},1) ifneq (${ARCH},aarch64) $(error USE_SPINLOCK_CAS requires AArch64) -else - $(info USE_SPINLOCK_CAS is an experimental feature) endif endif @@ -525,7 +523,6 @@ ifneq (${SPD},none) endif ifeq (${SPD},spmd) - $(warning "SPMD is an experimental feature") # SPMD is located in std_svc directory SPD_DIR := std_svc @@ -731,12 +728,7 @@ endif # SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled. ifeq ($(SDEI_SUPPORT)-$(SDEI_IN_FCONF),0-1) -$(error "SDEI_IN_FCONF is an experimental feature and is only supported when \ - SDEI_SUPPORT is enabled") -endif - -ifeq ($(COT_DESC_IN_DTB),1) - $(info CoT in device tree is an experimental feature) +$(error "SDEI_IN_FCONF is only supported when SDEI_SUPPORT is enabled") endif # If pointer authentication is used in the firmware, make sure that all the @@ -751,24 +743,12 @@ endif ifeq ($(CTX_INCLUDE_PAUTH_REGS),1) ifneq (${ARCH},aarch64) $(error CTX_INCLUDE_PAUTH_REGS requires AArch64) - else - $(info CTX_INCLUDE_PAUTH_REGS is an experimental feature) endif endif -ifeq ($(ENABLE_PAUTH),1) - $(info Pointer Authentication is an experimental feature) -endif - -ifeq ($(ENABLE_BTI),1) - $(info Branch Protection is an experimental feature) -endif - ifeq ($(CTX_INCLUDE_MTE_REGS),1) ifneq (${ARCH},aarch64) $(error CTX_INCLUDE_MTE_REGS requires AArch64) - else - $(info CTX_INCLUDE_MTE_REGS is an experimental feature) endif endif @@ -778,8 +758,6 @@ endif ifeq ($(MEASURED_BOOT),1) ifneq (${TRUSTED_BOARD_BOOT},1) $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1) - else - $(info MEASURED_BOOT is an experimental feature) endif endif @@ -796,8 +774,6 @@ endif ifneq (${DECRYPTION_SUPPORT},none) ifeq (${TRUSTED_BOARD_BOOT}, 0) $(error TRUSTED_BOARD_BOOT must be enabled for DECRYPTION_SUPPORT to be set) - else - $(info DECRYPTION_SUPPORT is an experimental feature) endif endif diff --git a/docs/about/features.rst b/docs/about/features.rst index f5fc1e044..4b7fbe56b 100644 --- a/docs/about/features.rst +++ b/docs/about/features.rst @@ -74,7 +74,7 @@ Current features loading of a hardware configuration (for example, a kernel device tree) as part of the FIP, to be passed through the firmware stages. This feature is now incorporated inside the firmware configuration framework - (fconf), which is still flagged as experimental. + (fconf). - Support for alternative boot flows, for example to support platforms where the EL3 Runtime Software is loaded using other firmware or a separate @@ -94,9 +94,7 @@ Current features - Support for ARMv8.3 pointer authentication in the normal and secure worlds. The use of pointer authentication in the normal world is enabled whenever architectural support is available, without the need for additional build - flags. Use of pointer authentication in the secure world remains an - experimental configuration at this time and requires the - ``BRANCH_PROTECTION`` option to be set to non-zero. + flags. - Position-Independent Executable (PIE) support. Currently for BL2, BL31, and TSP, with further support to be added in a future release. diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index c12e73f45..ef500ff05 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -2616,8 +2616,6 @@ Armv8.3-A ``CTX_INCLUDE_PAUTH_REGS`` to 1. This enables pointer authentication in BL1, BL2, BL31, and the TSP if it is used. - These options are experimental features. - Note that Pointer Authentication is enabled for Non-secure world irrespective of the value of these build flags if the CPU supports it. @@ -2629,8 +2627,7 @@ Armv8.5-A ~~~~~~~~~ - Branch Target Identification feature is selected by ``BRANCH_PROTECTION`` - option set to 1. This option defaults to 0 and this is an experimental - feature. + option set to 1. This option defaults to 0. - Memory Tagging Extension feature is unconditionally enabled for both worlds (at EL0 and S-EL0) if it is only supported at EL0. If instead it is diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst index 96cf24c0b..46177d768 100644 --- a/docs/design/trusted-board-boot.rst +++ b/docs/design/trusted-board-boot.rst @@ -239,9 +239,6 @@ optionally enabled on platforms to implement the optional requirement: R060_TBBR_FUNCTION as specified in the `Trusted Board Boot Requirements (TBBR)`_ document. -Note that due to security considerations and complexity of this feature, it is -marked as experimental. - Firmware Encryption Tool ------------------------ diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 1259881ed..8b5e92ecc 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -120,7 +120,7 @@ Common build options | 4 | bti | N | Y | +-------+--------------+-------+-----+ - This option defaults to 0 and this is an experimental feature. + This option defaults to 0. Note that Pointer Authentication is enabled for Non-secure world irrespective of the value of this option if the CPU supports it. @@ -181,7 +181,7 @@ Common build options - ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, enables Pointer Authentication for Secure world. This will cause the ARMv8.3-PAuth registers to be included when saving and restoring the CPU context as - part of world switch. Default value is 0 and this is an experimental feature. + part of world switch. Default value is 0. Note that Pointer Authentication is enabled for Non-secure world irrespective of the value of this flag if the CPU supports it. @@ -192,7 +192,7 @@ Common build options authenticated decryption algorithm to be used to decrypt firmware/s during boot. It accepts 2 values: ``aes_gcm`` and ``none``. The default value of this flag is ``none`` to disable firmware decryption which is an optional - feature as per TBBR. Also, it is an experimental feature. + feature as per TBBR. - ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation of the binary image. If set to 1, then only the ELF image is built. @@ -312,20 +312,18 @@ Common build options component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``. - ``ENCRYPT_BL31``: Binary flag to enable encryption of BL31 firmware. This - flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as - experimental. + flag depends on ``DECRYPTION_SUPPORT`` build flag. - ``ENCRYPT_BL32``: Binary flag to enable encryption of Secure BL32 payload. - This flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as - experimental. + This flag depends on ``DECRYPTION_SUPPORT`` build flag. - ``ENC_KEY``: A 32-byte (256-bit) symmetric key in hex string format. It could either be SSK or BSSK depending on ``FW_ENC_STATUS`` flag. This value depends - on ``DECRYPTION_SUPPORT`` build flag which is marked as experimental. + on ``DECRYPTION_SUPPORT`` build flag. - ``ENC_NONCE``: A 12-byte (96-bit) encryption nonce or Initialization Vector (IV) in hex string format. This value depends on ``DECRYPTION_SUPPORT`` - build flag which is marked as experimental. + build flag. - ``ERROR_DEPRECATED``: This option decides whether to treat the usage of deprecated platform APIs, helper functions or drivers within Trusted @@ -364,8 +362,7 @@ Common build options 1: Encryption is done with Binding Secret Symmetric Key (BSSK) which is unique per device. - This flag depends on ``DECRYPTION_SUPPORT`` build flag which is marked as - experimental. + This flag depends on ``DECRYPTION_SUPPORT`` build flag. - ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create`` tool to create certificates as per the Chain of Trust described in @@ -484,8 +481,7 @@ Common build options in order to provide trust that the code taking the measurements and recording them has not been tampered with. - This option defaults to 0 and is an experimental feature in the stage of - development. + This option defaults to 0. - ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the file that contains the Non-Trusted World private key in PEM @@ -695,26 +691,25 @@ Common build options - ``ARM_IO_IN_DTB``: This flag determines whether to use IO based on the firmware configuration framework. This will move the io_policies into a configuration device tree, instead of static structure in the code base. - This is currently an experimental feature. - ``COT_DESC_IN_DTB``: This flag determines whether to create COT descriptors at runtime using fconf. If this flag is enabled, COT descriptors are statically captured in tb_fw_config file in the form of device tree nodes and properties. Currently, COT descriptors used by BL2 are moved to the device tree and COT descriptors used by BL1 are retained in the code - base statically. This is currently an experimental feature. + base statically. - ``SDEI_IN_FCONF``: This flag determines whether to configure SDEI setup in runtime using firmware configuration framework. The platform specific SDEI shared and private events configuration is retrieved from device tree rather - than static C structures at compile time. This is currently an experimental - feature and is only supported if SDEI_SUPPORT build flag is enabled. + than static C structures at compile time. This is only supported if + SDEI_SUPPORT build flag is enabled. - ``SEC_INT_DESC_IN_FCONF``: This flag determines whether to configure Group 0 and Group1 secure interrupts using the firmware configuration framework. The platform specific secure interrupt property descriptor is retrieved from device tree in runtime rather than depending on static C structure at compile - time. This is currently an experimental feature. + time. - ``USE_ROMLIB``: This flag determines whether library at ROM will be used. This feature creates a library of functions to be placed in ROM and thus diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 6569a4768..57eba3ce2 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -891,8 +891,7 @@ symmetric key/identifier using img_id. On success the function should return 0 and a negative error code otherwise. -Note that this API depends on ``DECRYPTION_SUPPORT`` build flag which is -marked as experimental. +Note that this API depends on ``DECRYPTION_SUPPORT`` build flag. Function : plat_fwu_set_images_source() [when PSA_FWU_SUPPORT == 1] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/arm/gic/v3/gic600_multichip.c b/drivers/arm/gic/v3/gic600_multichip.c index fd3d8c207..5f42ad994 100644 --- a/drivers/arm/gic/v3/gic600_multichip.c +++ b/drivers/arm/gic/v3/gic600_multichip.c @@ -18,8 +18,6 @@ #include "../common/gic_common_private.h" #include "gic600_multichip_private.h" -#warning "GIC-600 Multichip driver is currently experimental and the API may change in future." - /******************************************************************************* * GIC-600 multichip operation related helper functions ******************************************************************************/ @@ -212,8 +210,6 @@ void gic600_multichip_init(struct gic600_multichip_data *multichip_data) gic600_multichip_validate_data(multichip_data); - INFO("GIC-600 Multichip driver is experimental\n"); - /* * Ensure that G0/G1S/G1NS interrupts are disabled. This also ensures * that GIC-600 Multichip configuration is done first. -- cgit v1.2.3 From 6b94356b577744d425476a029c47bd35eb13c148 Mon Sep 17 00:00:00 2001 From: Vasyl Gomonovych Date: Wed, 1 Sep 2021 10:30:55 -0700 Subject: fix(sdei): print event number in hex format SDEI specified event numbers in hexadecimal format. Change event number format to hexadecimal to make it easier for the reader to recognize the proper event. Change-Id: Iac7a91d0910316e0ad54a8f09bc17209e8c6adf6 Signed-off-by: Vasyl Gomonovych --- services/std_svc/sdei/sdei_intr_mgmt.c | 6 +++--- services/std_svc/sdei/sdei_main.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index 5d176c209..399c2ec91 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -531,7 +531,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle, if (is_event_shared(map)) sdei_map_unlock(map); - SDEI_LOG("ACK %llx, ev:%d ss:%d spsr:%lx ELR:%lx\n", mpidr, map->ev_num, + SDEI_LOG("ACK %llx, ev:0x%x ss:%d spsr:%lx ELR:%lx\n", mpidr, map->ev_num, sec_state, read_spsr_el3(), read_elr_el3()); ctx = handle; @@ -568,7 +568,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle, * interrupt. */ if ((map->ev_num != SDEI_EVENT_0) && !is_map_bound(map)) { - ERROR("Invalid SDEI mapping: ev=%u\n", map->ev_num); + ERROR("Invalid SDEI mapping: ev=0x%x\n", map->ev_num); panic(); } plat_ic_end_of_interrupt(intr_raw); @@ -703,7 +703,7 @@ int sdei_event_complete(bool resume, uint64_t pc) /* Having done sanity checks, pop dispatch */ (void) pop_dispatch(); - SDEI_LOG("EOI:%lx, %d spsr:%lx elr:%lx\n", read_mpidr_el1(), + SDEI_LOG("EOI:%lx, 0x%x spsr:%lx elr:%lx\n", read_mpidr_el1(), map->ev_num, read_spsr_el3(), read_elr_el3()); /* diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c index 5371df1e3..4ceaae891 100644 --- a/services/std_svc/sdei/sdei_main.c +++ b/services/std_svc/sdei/sdei_main.c @@ -966,7 +966,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, case SDEI_EVENT_REGISTER: x5 = SMC_GET_GP(ctx, CTX_GPREG_X5); - SDEI_LOG("> REG(n:%d e:%llx a:%llx f:%x m:%llx)\n", ev_num, + SDEI_LOG("> REG(n:0x%x e:%llx a:%llx f:%x m:%llx)\n", ev_num, x2, x3, (int) x4, x5); ret = sdei_event_register(ev_num, x2, x3, x4, x5); SDEI_LOG("< REG:%lld\n", ret); @@ -979,7 +979,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, SMC_RET1(ctx, ret); case SDEI_EVENT_DISABLE: - SDEI_LOG("> DISABLE(n:%d)\n", ev_num); + SDEI_LOG("> DISABLE(n:0x%x)\n", ev_num); ret = sdei_event_disable(ev_num); SDEI_LOG("< DISABLE:%lld\n", ret); SMC_RET1(ctx, ret); @@ -1013,19 +1013,19 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, SMC_RET0(ctx); case SDEI_EVENT_STATUS: - SDEI_LOG("> STAT(n:%d)\n", ev_num); + SDEI_LOG("> STAT(n:0x%x)\n", ev_num); ret = sdei_event_status(ev_num); SDEI_LOG("< STAT:%lld\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_GET_INFO: - SDEI_LOG("> INFO(n:%d, %d)\n", ev_num, (int) x2); + SDEI_LOG("> INFO(n:0x%x, %d)\n", ev_num, (int) x2); ret = sdei_event_get_info(ev_num, (int) x2); SDEI_LOG("< INFO:%lld\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_UNREGISTER: - SDEI_LOG("> UNREG(n:%d)\n", ev_num); + SDEI_LOG("> UNREG(n:0x%x)\n", ev_num); ret = sdei_event_unregister(ev_num); SDEI_LOG("< UNREG:%lld\n", ret); SMC_RET1(ctx, ret); @@ -1049,7 +1049,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, SMC_RET1(ctx, ret); case SDEI_INTERRUPT_RELEASE: - SDEI_LOG("> REL(%d)\n", ev_num); + SDEI_LOG("> REL(0x%x)\n", ev_num); ret = sdei_interrupt_release(ev_num); SDEI_LOG("< REL:%lld\n", ret); SMC_RET1(ctx, ret); @@ -1067,7 +1067,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, SMC_RET1(ctx, ret); case SDEI_EVENT_ROUTING_SET: - SDEI_LOG("> ROUTE_SET(n:%d f:%llx aff:%llx)\n", ev_num, x2, x3); + SDEI_LOG("> ROUTE_SET(n:0x%x f:%llx aff:%llx)\n", ev_num, x2, x3); ret = sdei_event_routing_set(ev_num, x2, x3); SDEI_LOG("< ROUTE_SET:%lld\n", ret); SMC_RET1(ctx, ret); @@ -1079,7 +1079,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, SMC_RET1(ctx, ret); case SDEI_EVENT_SIGNAL: - SDEI_LOG("> SIGNAL(e:%d t:%llx)\n", ev_num, x2); + SDEI_LOG("> SIGNAL(e:0x%x t:%llx)\n", ev_num, x2); ret = sdei_signal(ev_num, x2); SDEI_LOG("< SIGNAL:%lld\n", ret); SMC_RET1(ctx, ret); -- cgit v1.2.3 From 7186a29bbfe3044d5e8001ddfe1d9238578e0944 Mon Sep 17 00:00:00 2001 From: Vijayenthiran Subramaniam Date: Wed, 6 Oct 2021 15:12:25 +0530 Subject: feat(plat/arm/sgi): increase max BL2 size Increase `PLAT_ARM_MAX_BL2_SIZE` to 128KiB for the primary chip to accommodate debug builds with log level set to verbose (LOG_LEVEL=LOG_LEVEL_VERBOSE). Signed-off-by: Vijayenthiran Subramaniam Change-Id: I9dc835430f61b0d0c46a75f7a36d67f165293c8c --- plat/arm/css/sgi/include/sgi_base_platform_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index d795f258e..c9c8c0463 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -89,7 +89,7 @@ * */ #if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MAX_BL2_SIZE (0x1D000 + ((CSS_SGI_CHIP_COUNT - 1) * \ +# define PLAT_ARM_MAX_BL2_SIZE (0x20000 + ((CSS_SGI_CHIP_COUNT - 1) * \ 0x2000)) #else # define PLAT_ARM_MAX_BL2_SIZE (0x14000 + ((CSS_SGI_CHIP_COUNT - 1) * \ -- cgit v1.2.3 From b34635a02f3cce6a36e221cd7c33e33730b6e379 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 28 Sep 2021 15:44:19 +0100 Subject: build(bl1): deduplicate sources Deduplicating sources prevents the build system from complaining about multiply-compiled files, which can happen if multiple makefiles depend on a component. This already occurs for BL31. Signed-off-by: Chris Kay Change-Id: I9b40402f6f04600061fba7d6ad5d222a71e7d4a7 --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index ec6f88585..a1109643a 100644 --- a/Makefile +++ b/Makefile @@ -1185,6 +1185,8 @@ $(eval $(call MAKE_LIB,c)) # Expand build macros for the different images ifeq (${NEED_BL1},yes) +BL1_SOURCES := $(sort ${BL1_SOURCES}) + $(eval $(call MAKE_BL,bl1)) endif -- cgit v1.2.3 From eb1acfb60c6ddf5b72e9d68625a7ec046e895236 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 28 Sep 2021 15:44:37 +0100 Subject: build(bl2): deduplicate sources Deduplicating sources prevents the build system from complaining about multiply-compiled files, which can happen if multiple makefiles depend on a component. This already occurs for BL31. Signed-off-by: Chris Kay Change-Id: Ic9e67932550f07cb9e4d199f68bc46c33a611748 --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index a1109643a..814f98b5a 100644 --- a/Makefile +++ b/Makefile @@ -1195,6 +1195,8 @@ ifeq (${BL2_AT_EL3}, 0) FIP_BL2_ARGS := tb-fw endif +BL2_SOURCES := $(sort ${BL2_SOURCES}) + $(if ${BL2}, $(eval $(call TOOL_ADD_IMG,bl2,--${FIP_BL2_ARGS})),\ $(eval $(call MAKE_BL,bl2,${FIP_BL2_ARGS}))) endif -- cgit v1.2.3 From 1fa05dab070274eede406a5c33bb00b4c5a81fd0 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 28 Sep 2021 15:52:14 +0100 Subject: build(fdt-wrappers): introduce FDT wrappers makefile This has been introduced to simplify dependencies on the FDT wrappers. We generally want to avoid pulling in components on a file-by-file basis, particularly as we are trying to draw conceptual boxes around components in preparation for transitioning the build system to CMake, where dependencies are modelled on libraries rather than files. Signed-off-by: Chris Kay Change-Id: Idb7ee05a9b54a8caa3e07f36e608867e20b6dcd5 --- common/fdt_wrappers.mk | 7 +++++++ plat/arm/board/a5ds/platform.mk | 8 +++++--- plat/arm/board/arm_fpga/platform.mk | 6 ++++-- plat/arm/board/fvp/platform.mk | 7 +++++-- plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 9 ++++++--- plat/arm/board/fvp_ve/platform.mk | 8 +++++--- plat/arm/board/juno/platform.mk | 5 ++++- plat/arm/board/tc/platform.mk | 5 ++++- plat/arm/common/arm_common.mk | 7 +++++-- plat/nvidia/tegra/soc/t194/platform_t194.mk | 8 +++++--- plat/qemu/qemu_sbsa/platform.mk | 8 ++++++-- plat/st/stm32mp1/platform.mk | 6 ++++-- 12 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 common/fdt_wrappers.mk diff --git a/common/fdt_wrappers.mk b/common/fdt_wrappers.mk new file mode 100644 index 000000000..62b8c6e70 --- /dev/null +++ b/common/fdt_wrappers.mk @@ -0,0 +1,7 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +FDT_WRAPPERS_SOURCES := common/fdt_wrappers.c diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 8b0dc5cf3..88c92bd89 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -1,18 +1,20 @@ # -# Copyright (c) 2019-2020, Arm Limited. All rights reserved. +# Copyright (c) 2019-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # # Firmware Configuration Framework sources +include common/fdt_wrappers.mk include lib/fconf/fconf.mk # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \ - plat/arm/common/arm_dyn_cfg_helpers.c \ - common/fdt_wrappers.c + plat/arm/common/arm_dyn_cfg_helpers.c + +DYN_CFG_SOURCES += ${FDT_WRAPPERS_SOURCES} # Include GICv2 driver files include drivers/arm/gic/v2/gicv2.mk diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index 901fabf37..084532ce2 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -4,6 +4,7 @@ # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk include lib/libfdt/libfdt.mk RESET_TO_BL31 := 1 @@ -104,8 +105,7 @@ PLAT_INCLUDES := -Iplat/arm/board/arm_fpga/include PLAT_BL_COMMON_SOURCES := plat/arm/board/arm_fpga/${ARCH}/fpga_helpers.S -BL31_SOURCES += common/fdt_wrappers.c \ - common/fdt_fixup.c \ +BL31_SOURCES += common/fdt_fixup.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/arm/pl011/${ARCH}/pl011_console.S \ @@ -117,6 +117,8 @@ BL31_SOURCES += common/fdt_wrappers.c \ ${FPGA_CPU_LIBS} \ ${FPGA_GIC_SOURCES} +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31)) $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31)) $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31)) diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index fd27acb58..0d2c31971 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + # Use the GICv3 driver on the FVP by default FVP_USE_GIC_DRIVER := FVP_GICV3 @@ -228,11 +230,12 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ # Support for fconf in BL31 # Added separately from the above list for better readability ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) -BL31_SOURCES += common/fdt_wrappers.c \ - lib/fconf/fconf.c \ +BL31_SOURCES += lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + ifeq (${SEC_INT_DESC_IN_FCONF},1) BL31_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c endif diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk index 64cb7add5..0d8cca597 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -1,9 +1,11 @@ # -# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + # SP_MIN source files specific to FVP platform BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ drivers/cfi/v2m/v2m_flash.c \ @@ -22,10 +24,11 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ # Support for fconf in SP_MIN(BL32) # Added separately from the above list for better readability ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),) -BL32_SOURCES += common/fdt_wrappers.c \ - lib/fconf/fconf.c \ +BL32_SOURCES += lib/fconf/fconf.c \ plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +BL32_SOURCES += ${FDT_WRAPPERS_SOURCES} + ifeq (${SEC_INT_DESC_IN_FCONF},1) BL32_SOURCES += plat/arm/common/fconf/fconf_sec_intr_config.c endif diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index ac45d57ee..da4a96d7b 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -1,9 +1,11 @@ # -# Copyright (c) 2019-2020, Arm Limited. All rights reserved. +# Copyright (c) 2019-2021, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + ifdef ARM_CORTEX_A5 # Use the SP804 timer instead of the generic one USE_SP804_TIMER := 1 @@ -129,6 +131,6 @@ include lib/fconf/fconf.mk include lib/libfdt/libfdt.mk DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \ - plat/arm/common/arm_dyn_cfg_helpers.c \ - common/fdt_wrappers.c + plat/arm/common/arm_dyn_cfg_helpers.c +DYN_CFG_SOURCES += ${FDT_WRAPPERS_SOURCES} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index 92fbf3598..2c84eb34d 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + # Include GICv2 driver files include drivers/arm/gic/v2/gicv2.mk @@ -83,7 +85,6 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ lib/utils/mem_region.c \ - common/fdt_wrappers.c \ lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ plat/arm/board/juno/juno_bl31_setup.c \ @@ -94,6 +95,8 @@ BL31_SOURCES += drivers/cfi/v2m/v2m_flash.c \ ${JUNO_INTERCONNECT_SOURCES} \ ${JUNO_SECURITY_SOURCES} +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + ifeq (${CSS_USE_SCMI_SDS_DRIVER},1) BL1_SOURCES += drivers/arm/css/sds/sds.c endif diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index 7ebf6391d..f22cdc050 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -3,6 +3,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + ifeq ($(filter ${TARGET_PLATFORM}, 0 1),) $(error TARGET_PLATFORM must be 0 or 1) endif @@ -91,13 +93,14 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ ${ENT_GIC_SOURCES} \ ${TC_BASE}/tc_bl31_setup.c \ ${TC_BASE}/tc_topology.c \ - common/fdt_wrappers.c \ lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + # Add the FDT_SOURCES and options for Dynamic Config FDT_SOURCES += ${TC_BASE}/fdts/${PLAT}_fw_config.dts \ ${TC_BASE}/fdts/${PLAT}_tb_fw_config.dts diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a20e258a9..4d25bb2ab 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + ifeq (${ARCH}, aarch64) # On ARM standard platorms, the TSP can execute from Trusted SRAM, Trusted # DRAM (if available) or the TZC secured area of DRAM. @@ -261,9 +263,10 @@ include lib/libfdt/libfdt.mk DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \ plat/arm/common/arm_dyn_cfg_helpers.c \ - common/fdt_wrappers.c \ common/uuid.c +DYN_CFG_SOURCES += ${FDT_WRAPPERS_SOURCES} + BL1_SOURCES += ${DYN_CFG_SOURCES} BL2_SOURCES += ${DYN_CFG_SOURCES} @@ -343,10 +346,10 @@ endif ifeq (${SPD},spmd) BL31_SOURCES += plat/common/plat_spmd_manifest.c \ - common/fdt_wrappers.c \ common/uuid.c \ ${LIBFDT_SRCS} +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} endif ifneq (${TRUSTED_BOARD_BOOT},0) diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 339375f83..758383380 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -1,9 +1,11 @@ # -# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + # platform configs ENABLE_CONSOLE_SPE := 1 $(eval $(call add_define,ENABLE_CONSOLE_SPE)) @@ -74,10 +76,10 @@ endif # SPM dispatcher ifeq (${SPD},spmd) -# include device tree helper library include lib/libfdt/libfdt.mk # sources to support spmd BL31_SOURCES += plat/common/plat_spmd_manifest.c \ - common/fdt_wrappers.c \ ${LIBFDT_SRCS} + +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} endif diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 9fb30ad6c..5a6b1e11e 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -1,9 +1,11 @@ # -# Copyright (c) 2019-2020, Linaro Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2021, Linaro Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # +include common/fdt_wrappers.mk + CRASH_REPORTING := 1 include lib/libfdt/libfdt.mk @@ -86,8 +88,10 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a57.S \ ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ common/fdt_fixup.c \ - common/fdt_wrappers.c \ ${QEMU_GIC_SOURCES} + +BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} + ifeq (${SPM_MM},1) BL31_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_spm.c endif diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 28463f1f5..14f90d466 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -154,13 +154,15 @@ $(eval $(call add_defines,\ PLAT_INCLUDES := -Iplat/st/common/include/ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ +include common/fdt_wrappers.mk include lib/libfdt/libfdt.mk -PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ - common/uuid.c \ +PLAT_BL_COMMON_SOURCES := common/uuid.c \ plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c +PLAT_BL_COMMON_SOURCES += ${FDT_WRAPPERS_SOURCES} + PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S ifneq (${ENABLE_STACK_PROTECTOR},0) -- cgit v1.2.3 From 2d9ea360350303e37a8dd39f3599ac88aaef0ff9 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 28 Sep 2021 16:06:25 +0100 Subject: feat(fdt-wrappers): add CPU enumeration utility function This change adds a new utility function - `fdtw_for_each_cpu` - to invoke a callback for every CPU node listed in a flattened device tree (FDT) with the node identifier and the MPIDR of the core it describes. Signed-off-by: Chris Kay Change-Id: Iabb5c0f0c9d11928a4a7a41cdc7d1e09aadeb2bc --- common/fdt_wrappers.c | 44 +++++++++++++++++++++++++++++++++++++++++++ include/common/fdt_wrappers.h | 3 +++ 2 files changed, 47 insertions(+) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index dd7a0faef..64e01ea6d 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -572,3 +572,47 @@ uint64_t fdtw_translate_address(const void *dtb, int node, /* Translate the local device address recursively */ return fdtw_translate_address(dtb, local_bus_node, global_address); } + +/* + * For every CPU node (`/cpus/cpu@n`) in an FDT, execute a callback passing a + * pointer to the FDT and the offset of the CPU node. If the return value of the + * callback is negative, it is treated as an error and the loop is aborted. In + * this situation, the value of the callback is returned from the function. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +int fdtw_for_each_cpu(const void *dtb, + int (*callback)(const void *dtb, int node, uintptr_t mpidr)) +{ + int ret = 0; + int parent, node = 0; + + parent = fdt_path_offset(dtb, "/cpus"); + if (parent < 0) { + return parent; + } + + fdt_for_each_subnode(node, dtb, parent) { + const char *name; + int len; + + uintptr_t mpidr = 0U; + + name = fdt_get_name(dtb, node, &len); + if (strncmp(name, "cpu@", 4) != 0) { + continue; + } + + ret = fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL); + if (ret < 0) { + break; + } + + ret = callback(dtb, node, mpidr); + if (ret < 0) { + break; + } + } + + return ret; +} diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index 98e7a3e6f..9c7180c5e 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -41,6 +41,9 @@ int fdt_get_stdout_node_offset(const void *dtb); uint64_t fdtw_translate_address(const void *dtb, int bus_node, uint64_t base_address); +int fdtw_for_each_cpu(const void *fdt, + int (*callback)(const void *dtb, int node, uintptr_t mpidr)); + static inline uint32_t fdt_blob_size(const void *dtb) { const uint32_t *dtb_header = dtb; -- cgit v1.2.3 From e04da4c8e132f43218f18ad3b41479ca54bb9263 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 20 May 2021 13:22:43 +0100 Subject: build(fconf)!: clean up source collection Including the FCONF Makefile today automatically places the FCONF sources into the source list of the BL1 and BL2 images. This may be undesirable if, for instance, FCONF is only required for BL31. This change moves the BL1 and BL2 source appends out of the common Makefile to where they are required. BREAKING CHANGE: FCONF is no longer added to BL1 and BL2 automatically when the FCONF Makefile (`fconf.mk`) is included. When including this Makefile, consider whether you need to add `${FCONF_SOURCES}` and `${FCONF_DYN_SOURCES}` to `BL1_SOURCES` and `BL2_SOURCES`. Change-Id: Ic028eabb7437ae95a57c5bcb7821044d31755c77 Signed-off-by: Chris Kay --- lib/fconf/fconf.mk | 11 ++++++----- plat/arm/board/a5ds/platform.mk | 3 +++ plat/arm/board/fvp_ve/platform.mk | 3 +++ plat/arm/common/arm_common.mk | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index b01dc6fea..bc6f60840 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -1,12 +1,13 @@ # -# Copyright (c) 2019-2020, ARM Limited. All rights reserved. +# Copyright (c) 2019-2021, ARM Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # -# Add Firmware Configuration files +include common/fdt_wrappers.mk + FCONF_SOURCES := lib/fconf/fconf.c -FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c +FCONF_SOURCES += ${FDT_WRAPPERS_SOURCES} -BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} -BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} +FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c +FCONF_DYN_SOURCES += ${FDT_WRAPPERS_SOURCES} diff --git a/plat/arm/board/a5ds/platform.mk b/plat/arm/board/a5ds/platform.mk index 88c92bd89..4f873069a 100644 --- a/plat/arm/board/a5ds/platform.mk +++ b/plat/arm/board/a5ds/platform.mk @@ -8,6 +8,9 @@ include common/fdt_wrappers.mk include lib/fconf/fconf.mk +BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/board/fvp_ve/platform.mk b/plat/arm/board/fvp_ve/platform.mk index da4a96d7b..f7eace833 100644 --- a/plat/arm/board/fvp_ve/platform.mk +++ b/plat/arm/board/fvp_ve/platform.mk @@ -127,6 +127,9 @@ endif # Firmware Configuration Framework sources include lib/fconf/fconf.mk +BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 4d25bb2ab..78efb0f90 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -258,6 +258,9 @@ BL2_SOURCES += drivers/delay_timer/delay_timer.c \ # Firmware Configuration Framework sources include lib/fconf/fconf.mk +BL1_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} +BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} + # Add `libfdt` and Arm common helpers required for Dynamic Config include lib/libfdt/libfdt.mk -- cgit v1.2.3 From 9b43d098d892d39f79be7738cff15bbef5979ed8 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Wed, 19 May 2021 19:24:37 +0100 Subject: build(amu): introduce `amu.mk` This change introduces the `amu.mk` Makefile, used to remove the need to manually include AMU sources into the various build images. Makefiles requiring the list of AMU sources are expected to include this file and use `${AMU_SOURCES}` to retrieve them. Change-Id: I3d174033ecdce6439a110d776f0c064c67abcfe0 Signed-off-by: Chris Kay --- bl31/bl31.mk | 4 ++-- bl32/sp_min/sp_min.mk | 8 ++++---- lib/extensions/amu/amu.mk | 8 ++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 lib/extensions/amu/amu.mk diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 106d4109d..4e9e99f46 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -22,6 +22,7 @@ ifeq (${SPM_MM},1) endif endif +include lib/extensions/amu/amu.mk include lib/psci/psci_lib.mk BL31_SOURCES += bl31/bl31_main.c \ @@ -78,8 +79,7 @@ BL31_SOURCES += lib/extensions/spe/spe.c endif ifeq (${ENABLE_AMU},1) -BL31_SOURCES += lib/extensions/amu/aarch64/amu.c \ - lib/extensions/amu/aarch64/amu_helpers.S +BL31_SOURCES += ${AMU_SOURCES} endif ifeq (${ENABLE_SVE_FOR_NS},1) diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk index 6339cf856..590b0327a 100644 --- a/bl32/sp_min/sp_min.mk +++ b/bl32/sp_min/sp_min.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,7 @@ ifneq (${ARCH}, aarch32) $(error SP_MIN is only supported on AArch32 platforms) endif +include lib/extensions/amu/amu.mk include lib/psci/psci_lib.mk INCLUDES += -Iinclude/bl32/sp_min @@ -27,9 +28,8 @@ ifeq (${ENABLE_PMF}, 1) BL32_SOURCES += lib/pmf/pmf_main.c endif -ifeq (${ENABLE_AMU}, 1) -BL32_SOURCES += lib/extensions/amu/aarch32/amu.c\ - lib/extensions/amu/aarch32/amu_helpers.S +ifeq (${ENABLE_AMU},1) +BL32_SOURCES += ${AMU_SOURCES} endif ifeq (${WORKAROUND_CVE_2017_5715},1) diff --git a/lib/extensions/amu/amu.mk b/lib/extensions/amu/amu.mk new file mode 100644 index 000000000..b4e04dd47 --- /dev/null +++ b/lib/extensions/amu/amu.mk @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +AMU_SOURCES := lib/extensions/amu/${ARCH}/amu.c \ + lib/extensions/amu/${ARCH}/amu_helpers.S -- cgit v1.2.3 From 6c8dda19e5f484f8544365fd71d965f0afc39244 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Mon, 17 May 2021 14:47:25 +0100 Subject: refactor(amu)!: remove `PLAT_AMU_GROUP1_COUNTERS_MASK` With the introduction of MPMM, the auxiliary AMU counter logic requires refactoring to move away from a single platform-defined group 1 counter mask in order to support microarchitectural (per-core) group 1 counters. BREAKING CHANGE: The `PLAT_AMU_GROUP1_COUNTERS_MASK` platform definition has been removed. Platforms should specify per-core AMU counter masks via FCONF or a platform-specific mechanism going forward. Change-Id: I1e852797c7954f92409222b066a1ae57bc72bb05 Signed-off-by: Chris Kay --- docs/getting_started/porting-guide.rst | 9 --------- include/lib/extensions/amu.h | 4 ---- 2 files changed, 13 deletions(-) diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 6569a4768..6f577f942 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -562,15 +562,6 @@ behaviour of the ``assert()`` function (for example, to save memory). doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't defined, it defaults to ``LOG_LEVEL``. -If the platform port uses the Activity Monitor Unit, the following constant -may be defined: - -- **PLAT_AMU_GROUP1_COUNTERS_MASK** - This mask reflects the set of group counters that should be enabled. The - maximum number of group 1 counters supported by AMUv1 is 16 so the mask - can be at most 0xffff. If the platform does not define this mask, no group 1 - counters are enabled. - File : plat_macros.S [mandatory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h index 3a254c9b1..768e72c25 100644 --- a/include/lib/extensions/amu.h +++ b/include/lib/extensions/amu.h @@ -20,11 +20,7 @@ #define AMU_GROUP0_COUNTERS_MASK U(0xf) #define AMU_GROUP0_NR_COUNTERS U(4) -#ifdef PLAT_AMU_GROUP1_COUNTERS_MASK -#define AMU_GROUP1_COUNTERS_MASK PLAT_AMU_GROUP1_COUNTERS_MASK -#else #define AMU_GROUP1_COUNTERS_MASK U(0) -#endif /* Calculate number of group 1 counters */ #if (AMU_GROUP1_COUNTERS_MASK & (1 << 15)) -- cgit v1.2.3 From b4b726ea868359cf683c07337b69fe91a2a6929a Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Mon, 24 May 2021 21:00:07 +0100 Subject: refactor(amu)!: privatize unused AMU APIs This change reduces the exposed surface area of the AMU API in order to simplify the refactoring work in following patches. The functions and definitions privatized by this change are not used by other parts of the code-base today. BREAKING CHANGE: The public AMU API has been reduced to enablement only to facilitate refactoring work. These APIs were not previously used. Change-Id: Ibf6174fb5b3949de3c4ba6847cce47d82a6bd08c Signed-off-by: Chris Kay --- include/lib/extensions/amu.h | 91 ------------------------------------ include/lib/extensions/amu_private.h | 66 ++++++++++++++++++++++++++ lib/extensions/amu/aarch32/amu.c | 26 +++-------- lib/extensions/amu/aarch64/amu.c | 34 ++++---------- 4 files changed, 82 insertions(+), 135 deletions(-) diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h index 768e72c25..692d1adaf 100644 --- a/include/lib/extensions/amu.h +++ b/include/lib/extensions/amu.h @@ -8,103 +8,12 @@ #define AMU_H #include -#include - -#include -#include - #include -#include - -/* All group 0 counters */ -#define AMU_GROUP0_COUNTERS_MASK U(0xf) -#define AMU_GROUP0_NR_COUNTERS U(4) - -#define AMU_GROUP1_COUNTERS_MASK U(0) - -/* Calculate number of group 1 counters */ -#if (AMU_GROUP1_COUNTERS_MASK & (1 << 15)) -#define AMU_GROUP1_NR_COUNTERS 16U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 14)) -#define AMU_GROUP1_NR_COUNTERS 15U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 13)) -#define AMU_GROUP1_NR_COUNTERS 14U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 12)) -#define AMU_GROUP1_NR_COUNTERS 13U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 11)) -#define AMU_GROUP1_NR_COUNTERS 12U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 10)) -#define AMU_GROUP1_NR_COUNTERS 11U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 9)) -#define AMU_GROUP1_NR_COUNTERS 10U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 8)) -#define AMU_GROUP1_NR_COUNTERS 9U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 7)) -#define AMU_GROUP1_NR_COUNTERS 8U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 6)) -#define AMU_GROUP1_NR_COUNTERS 7U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 5)) -#define AMU_GROUP1_NR_COUNTERS 6U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 4)) -#define AMU_GROUP1_NR_COUNTERS 5U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 3)) -#define AMU_GROUP1_NR_COUNTERS 4U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 2)) -#define AMU_GROUP1_NR_COUNTERS 3U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 1)) -#define AMU_GROUP1_NR_COUNTERS 2U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 0)) -#define AMU_GROUP1_NR_COUNTERS 1U -#else -#define AMU_GROUP1_NR_COUNTERS 0U -#endif - -CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); - -struct amu_ctx { - uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; -#if __aarch64__ - /* Architected event counter 1 does not have an offset register. */ - uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1]; -#endif - -#if AMU_GROUP1_NR_COUNTERS - uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; -#if __aarch64__ - uint64_t group1_voffsets[AMU_GROUP1_NR_COUNTERS]; -#endif -#endif -}; -unsigned int amu_get_version(void); #if __aarch64__ void amu_enable(bool el2_unused, cpu_context_t *ctx); #else void amu_enable(bool el2_unused); #endif -/* Group 0 configuration helpers */ -uint64_t amu_group0_cnt_read(unsigned int idx); -void amu_group0_cnt_write(unsigned int idx, uint64_t val); - -#if __aarch64__ -uint64_t amu_group0_voffset_read(unsigned int idx); -void amu_group0_voffset_write(unsigned int idx, uint64_t val); -#endif - -#if AMU_GROUP1_NR_COUNTERS -bool amu_group1_supported(void); - -/* Group 1 configuration helpers */ -uint64_t amu_group1_cnt_read(unsigned int idx); -void amu_group1_cnt_write(unsigned int idx, uint64_t val); -void amu_group1_set_evtype(unsigned int idx, unsigned int val); - -#if __aarch64__ -uint64_t amu_group1_voffset_read(unsigned int idx); -void amu_group1_voffset_write(unsigned int idx, uint64_t val); -#endif - -#endif - #endif /* AMU_H */ diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h index 3b4b47ca3..9fe16441e 100644 --- a/include/lib/extensions/amu_private.h +++ b/include/lib/extensions/amu_private.h @@ -9,6 +9,72 @@ #include +#include +#include +#include + +#include + +/* All group 0 counters */ +#define AMU_GROUP0_COUNTERS_MASK U(0xf) +#define AMU_GROUP0_NR_COUNTERS U(4) + +#define AMU_GROUP1_COUNTERS_MASK U(0) + +/* Calculate number of group 1 counters */ +#if (AMU_GROUP1_COUNTERS_MASK & (1 << 15)) +#define AMU_GROUP1_NR_COUNTERS 16U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 14)) +#define AMU_GROUP1_NR_COUNTERS 15U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 13)) +#define AMU_GROUP1_NR_COUNTERS 14U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 12)) +#define AMU_GROUP1_NR_COUNTERS 13U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 11)) +#define AMU_GROUP1_NR_COUNTERS 12U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 10)) +#define AMU_GROUP1_NR_COUNTERS 11U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 9)) +#define AMU_GROUP1_NR_COUNTERS 10U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 8)) +#define AMU_GROUP1_NR_COUNTERS 9U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 7)) +#define AMU_GROUP1_NR_COUNTERS 8U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 6)) +#define AMU_GROUP1_NR_COUNTERS 7U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 5)) +#define AMU_GROUP1_NR_COUNTERS 6U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 4)) +#define AMU_GROUP1_NR_COUNTERS 5U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 3)) +#define AMU_GROUP1_NR_COUNTERS 4U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 2)) +#define AMU_GROUP1_NR_COUNTERS 3U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 1)) +#define AMU_GROUP1_NR_COUNTERS 2U +#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 0)) +#define AMU_GROUP1_NR_COUNTERS 1U +#else +#define AMU_GROUP1_NR_COUNTERS 0U +#endif + +CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); + +struct amu_ctx { + uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; +#if __aarch64__ + /* Architected event counter 1 does not have an offset register. */ + uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1]; +#endif + +#if AMU_GROUP1_NR_COUNTERS + uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; +#if __aarch64__ + uint64_t group1_voffsets[AMU_GROUP1_NR_COUNTERS]; +#endif +#endif +}; + uint64_t amu_group0_cnt_read_internal(unsigned int idx); void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val); diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index ed56dddc9..8896e5c69 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -25,7 +25,7 @@ static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; * ID_PFR0_AMU_V1P1: FEAT_AMUv1p1 supported (introduced in ARM v8.6) * ID_PFR0_AMU_NOT_SUPPORTED: not supported */ -unsigned int amu_get_version(void) +static unsigned int amu_get_version(void) { return (unsigned int)(read_id_pfr0() >> ID_PFR0_AMU_SHIFT) & ID_PFR0_AMU_MASK; @@ -33,7 +33,7 @@ unsigned int amu_get_version(void) #if AMU_GROUP1_NR_COUNTERS /* Check if group 1 counters is implemented */ -bool amu_group1_supported(void) +static bool amu_group1_supported(void) { uint32_t features = read_amcfgr() >> AMCFGR_NCG_SHIFT; @@ -113,7 +113,7 @@ void amu_enable(bool el2_unused) } /* Read the group 0 counter identified by the given `idx`. */ -uint64_t amu_group0_cnt_read(unsigned int idx) +static uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -122,7 +122,7 @@ uint64_t amu_group0_cnt_read(unsigned int idx) } /* Write the group 0 counter identified by the given `idx` with `val` */ -void amu_group0_cnt_write(unsigned int idx, uint64_t val) +static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -133,7 +133,7 @@ void amu_group0_cnt_write(unsigned int idx, uint64_t val) #if AMU_GROUP1_NR_COUNTERS /* Read the group 1 counter identified by the given `idx` */ -uint64_t amu_group1_cnt_read(unsigned int idx) +static uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); assert(amu_group1_supported()); @@ -143,7 +143,7 @@ uint64_t amu_group1_cnt_read(unsigned int idx) } /* Write the group 1 counter identified by the given `idx` with `val` */ -void amu_group1_cnt_write(unsigned int idx, uint64_t val) +static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); assert(amu_group1_supported()); @@ -152,20 +152,6 @@ void amu_group1_cnt_write(unsigned int idx, uint64_t val) amu_group1_cnt_write_internal(idx, val); isb(); } - -/* - * Program the event type register for the given `idx` with - * the event number `val` - */ -void amu_group1_set_evtype(unsigned int idx, unsigned int val) -{ - assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); - assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); - - amu_group1_set_evtype_internal(idx, val); - isb(); -} #endif /* AMU_GROUP1_NR_COUNTERS */ static void *amu_context_save(const void *arg) diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 295c0d569..97eb1e366 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -26,7 +26,7 @@ static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; * ID_AA64PFR0_AMU_V1P1: FEAT_AMUv1p1 supported (introduced in ARM v8.6) * ID_AA64PFR0_AMU_NOT_SUPPORTED: not supported */ -unsigned int amu_get_version(void) +static unsigned int amu_get_version(void) { return (unsigned int)(read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & ID_AA64PFR0_AMU_MASK; @@ -34,7 +34,7 @@ unsigned int amu_get_version(void) #if AMU_GROUP1_NR_COUNTERS /* Check if group 1 counters is implemented */ -bool amu_group1_supported(void) +static bool amu_group1_supported(void) { uint64_t features = read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT; @@ -130,7 +130,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) } /* Read the group 0 counter identified by the given `idx`. */ -uint64_t amu_group0_cnt_read(unsigned int idx) +static uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -139,7 +139,7 @@ uint64_t amu_group0_cnt_read(unsigned int idx) } /* Write the group 0 counter identified by the given `idx` with `val` */ -void amu_group0_cnt_write(unsigned int idx, uint64_t val) +static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -154,7 +154,7 @@ void amu_group0_cnt_write(unsigned int idx, uint64_t val) * * Using this function requires FEAT_AMUv1p1 support. */ -uint64_t amu_group0_voffset_read(unsigned int idx) +static uint64_t amu_group0_voffset_read(unsigned int idx) { assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -169,7 +169,7 @@ uint64_t amu_group0_voffset_read(unsigned int idx) * * Using this function requires FEAT_AMUv1p1 support. */ -void amu_group0_voffset_write(unsigned int idx, uint64_t val) +static void amu_group0_voffset_write(unsigned int idx, uint64_t val) { assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); assert(idx < AMU_GROUP0_NR_COUNTERS); @@ -181,7 +181,7 @@ void amu_group0_voffset_write(unsigned int idx, uint64_t val) #if AMU_GROUP1_NR_COUNTERS /* Read the group 1 counter identified by the given `idx` */ -uint64_t amu_group1_cnt_read(unsigned int idx) +static uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); assert(amu_group1_supported()); @@ -191,7 +191,7 @@ uint64_t amu_group1_cnt_read(unsigned int idx) } /* Write the group 1 counter identified by the given `idx` with `val` */ -void amu_group1_cnt_write(unsigned int idx, uint64_t val) +static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); assert(amu_group1_supported()); @@ -206,7 +206,7 @@ void amu_group1_cnt_write(unsigned int idx, uint64_t val) * * Using this function requires FEAT_AMUv1p1 support. */ -uint64_t amu_group1_voffset_read(unsigned int idx) +static uint64_t amu_group1_voffset_read(unsigned int idx) { assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); assert(amu_group1_supported()); @@ -222,7 +222,7 @@ uint64_t amu_group1_voffset_read(unsigned int idx) * * Using this function requires FEAT_AMUv1p1 support. */ -void amu_group1_voffset_write(unsigned int idx, uint64_t val) +static void amu_group1_voffset_write(unsigned int idx, uint64_t val) { assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); assert(amu_group1_supported()); @@ -233,20 +233,6 @@ void amu_group1_voffset_write(unsigned int idx, uint64_t val) amu_group1_voffset_write_internal(idx, val); isb(); } - -/* - * Program the event type register for the given `idx` with - * the event number `val` - */ -void amu_group1_set_evtype(unsigned int idx, unsigned int val) -{ - assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); - assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); - - amu_group1_set_evtype_internal(idx, val); - isb(); -} #endif /* AMU_GROUP1_NR_COUNTERS */ static void *amu_context_save(const void *arg) -- cgit v1.2.3 From 33b9be6d758d4fcef1f5a9802a54bb56f2c4ff8d Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Wed, 26 May 2021 11:58:23 +0100 Subject: refactor(amu): factor out register accesses This change introduces a small set of register getters and setters to avoid having to repeatedly mask and shift in complex code. Change-Id: Ia372f60c5efb924cd6eeceb75112e635ad13d942 Signed-off-by: Chris Kay --- include/arch/aarch32/arch.h | 22 +++- include/arch/aarch64/arch.h | 28 ++++- lib/extensions/amu/aarch32/amu.c | 157 ++++++++++++++++++++------- lib/extensions/amu/aarch64/amu.c | 225 +++++++++++++++++++++++++++------------ 4 files changed, 317 insertions(+), 115 deletions(-) diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 7221b6273..59680b7c6 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -253,7 +253,8 @@ /* HCPTR definitions */ #define HCPTR_RES1 ((U(1) << 13) | (U(1) << 12) | U(0x3ff)) #define TCPAC_BIT (U(1) << 31) -#define TAM_BIT (U(1) << 30) +#define TAM_SHIFT U(30) +#define TAM_BIT (U(1) << TAM_SHIFT) #define TTA_BIT (U(1) << 20) #define TCP11_BIT (U(1) << 11) #define TCP10_BIT (U(1) << 10) @@ -727,8 +728,25 @@ #define AMEVTYPER1E p15, 0, c13, c15, 6 #define AMEVTYPER1F p15, 0, c13, c15, 7 +/* AMCNTENSET0 definitions */ +#define AMCNTENSET0_Pn_SHIFT U(0) +#define AMCNTENSET0_Pn_MASK U(0xffff) + +/* AMCNTENSET1 definitions */ +#define AMCNTENSET1_Pn_SHIFT U(0) +#define AMCNTENSET1_Pn_MASK U(0xffff) + +/* AMCNTENCLR0 definitions */ +#define AMCNTENCLR0_Pn_SHIFT U(0) +#define AMCNTENCLR0_Pn_MASK U(0xffff) + +/* AMCNTENCLR1 definitions */ +#define AMCNTENCLR1_Pn_SHIFT U(0) +#define AMCNTENCLR1_Pn_MASK U(0xffff) + /* AMCR definitions */ -#define AMCR_CG1RZ_BIT (ULL(1) << 17) +#define AMCR_CG1RZ_SHIFT U(17) +#define AMCR_CG1RZ_BIT (ULL(1) << AMCR_CG1RZ_SHIFT) /* AMCFGR definitions */ #define AMCFGR_NCG_SHIFT U(28) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 74bc8cb8a..a72087e8f 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -532,7 +532,8 @@ /* HCR definitions */ #define HCR_RESET_VAL ULL(0x0) -#define HCR_AMVOFFEN_BIT (ULL(1) << 51) +#define HCR_AMVOFFEN_SHIFT U(51) +#define HCR_AMVOFFEN_BIT (ULL(1) << HCR_AMVOFFEN_SHIFT) #define HCR_TEA_BIT (ULL(1) << 47) #define HCR_API_BIT (ULL(1) << 41) #define HCR_APK_BIT (ULL(1) << 40) @@ -570,7 +571,8 @@ /* CPTR_EL3 definitions */ #define TCPAC_BIT (U(1) << 31) -#define TAM_BIT (U(1) << 30) +#define TAM_SHIFT U(30) +#define TAM_BIT (U(1) << TAM_SHIFT) #define TTA_BIT (U(1) << 20) #define TFP_BIT (U(1) << 10) #define CPTR_EZ_BIT (U(1) << 8) @@ -579,7 +581,8 @@ /* CPTR_EL2 definitions */ #define CPTR_EL2_RES1 ((U(1) << 13) | (U(1) << 12) | (U(0x3ff))) #define CPTR_EL2_TCPAC_BIT (U(1) << 31) -#define CPTR_EL2_TAM_BIT (U(1) << 30) +#define CPTR_EL2_TAM_SHIFT U(30) +#define CPTR_EL2_TAM_BIT (U(1) << CPTR_EL2_TAM_SHIFT) #define CPTR_EL2_TTA_BIT (U(1) << 20) #define CPTR_EL2_TFP_BIT (U(1) << 10) #define CPTR_EL2_TZ_BIT (U(1) << 8) @@ -1043,6 +1046,22 @@ #define AMEVTYPER1E_EL0 S3_3_C13_C15_6 #define AMEVTYPER1F_EL0 S3_3_C13_C15_7 +/* AMCNTENSET0_EL0 definitions */ +#define AMCNTENSET0_EL0_Pn_SHIFT U(0) +#define AMCNTENSET0_EL0_Pn_MASK ULL(0xffff) + +/* AMCNTENSET1_EL0 definitions */ +#define AMCNTENSET1_EL0_Pn_SHIFT U(0) +#define AMCNTENSET1_EL0_Pn_MASK ULL(0xffff) + +/* AMCNTENCLR0_EL0 definitions */ +#define AMCNTENCLR0_EL0_Pn_SHIFT U(0) +#define AMCNTENCLR0_EL0_Pn_MASK ULL(0xffff) + +/* AMCNTENCLR1_EL0 definitions */ +#define AMCNTENCLR1_EL0_Pn_SHIFT U(0) +#define AMCNTENCLR1_EL0_Pn_MASK ULL(0xffff) + /* AMCFGR_EL0 definitions */ #define AMCFGR_EL0_NCG_SHIFT U(28) #define AMCFGR_EL0_NCG_MASK U(0xf) @@ -1074,7 +1093,8 @@ #define AMCG1IDR_VOFF_SHIFT U(16) /* New bit added to AMCR_EL0 */ -#define AMCR_CG1RZ_BIT (ULL(0x1) << 17) +#define AMCR_CG1RZ_SHIFT U(17) +#define AMCR_CG1RZ_BIT (ULL(0x1) << AMCR_CG1RZ_SHIFT) /* * Definitions for virtual offset registers for architected activity monitor diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 8896e5c69..2fc35094f 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -18,26 +19,104 @@ static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; -/* - * Get AMU version value from pfr0. - * Return values - * ID_PFR0_AMU_V1: FEAT_AMUv1 supported (introduced in ARM v8.4) - * ID_PFR0_AMU_V1P1: FEAT_AMUv1p1 supported (introduced in ARM v8.6) - * ID_PFR0_AMU_NOT_SUPPORTED: not supported - */ -static unsigned int amu_get_version(void) +static inline __unused uint32_t read_id_pfr0_amu(void) { - return (unsigned int)(read_id_pfr0() >> ID_PFR0_AMU_SHIFT) & + return (read_id_pfr0() >> ID_PFR0_AMU_SHIFT) & ID_PFR0_AMU_MASK; } -#if AMU_GROUP1_NR_COUNTERS -/* Check if group 1 counters is implemented */ -static bool amu_group1_supported(void) +static inline __unused void write_hcptr_tam(uint32_t value) { - uint32_t features = read_amcfgr() >> AMCFGR_NCG_SHIFT; + write_hcptr((read_hcptr() & ~TAM_BIT) | + ((value << TAM_SHIFT) & TAM_BIT)); +} - return (features & AMCFGR_NCG_MASK) == 1U; +static inline __unused void write_amcr_cg1rz(uint32_t value) +{ + write_amcr((read_amcr() & ~AMCR_CG1RZ_BIT) | + ((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT)); +} + +static inline __unused uint32_t read_amcfgr_ncg(void) +{ + return (read_amcfgr() >> AMCFGR_NCG_SHIFT) & + AMCFGR_NCG_MASK; +} + +static inline __unused uint32_t read_amcgcr_cg1nc(void) +{ + return (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) & + AMCGCR_CG1NC_MASK; +} + +static inline __unused uint32_t read_amcntenset0_px(void) +{ + return (read_amcntenset0() >> AMCNTENSET0_Pn_SHIFT) & + AMCNTENSET0_Pn_MASK; +} + +static inline __unused uint32_t read_amcntenset1_px(void) +{ + return (read_amcntenset1() >> AMCNTENSET1_Pn_SHIFT) & + AMCNTENSET1_Pn_MASK; +} + +static inline __unused void write_amcntenset0_px(uint32_t px) +{ + uint32_t value = read_amcntenset0(); + + value &= ~AMCNTENSET0_Pn_MASK; + value |= (px << AMCNTENSET0_Pn_SHIFT) & + AMCNTENSET0_Pn_MASK; + + write_amcntenset0(value); +} + +static inline __unused void write_amcntenset1_px(uint32_t px) +{ + uint32_t value = read_amcntenset1(); + + value &= ~AMCNTENSET1_Pn_MASK; + value |= (px << AMCNTENSET1_Pn_SHIFT) & + AMCNTENSET1_Pn_MASK; + + write_amcntenset1(value); +} + +static inline __unused void write_amcntenclr0_px(uint32_t px) +{ + uint32_t value = read_amcntenclr0(); + + value &= ~AMCNTENCLR0_Pn_MASK; + value |= (px << AMCNTENCLR0_Pn_SHIFT) & AMCNTENCLR0_Pn_MASK; + + write_amcntenclr0(value); +} + +static inline __unused void write_amcntenclr1_px(uint32_t px) +{ + uint32_t value = read_amcntenclr1(); + + value &= ~AMCNTENCLR1_Pn_MASK; + value |= (px << AMCNTENCLR1_Pn_SHIFT) & AMCNTENCLR1_Pn_MASK; + + write_amcntenclr1(value); +} + +static bool amu_supported(void) +{ + return read_id_pfr0_amu() >= ID_PFR0_AMU_V1; +} + +static bool amu_v1p1_supported(void) +{ + return read_id_pfr0_amu() >= ID_PFR0_AMU_V1P1; +} + +#if ENABLE_AMU_AUXILIARY_COUNTERS +static bool amu_group1_supported(void) +{ + return read_amcfgr_ncg() > 0U; } #endif @@ -47,7 +126,7 @@ static bool amu_group1_supported(void) */ void amu_enable(bool el2_unused) { - if (amu_get_version() == ID_PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return; } @@ -59,8 +138,7 @@ void amu_enable(bool el2_unused) } /* Check number of group 1 counters */ - uint32_t cnt_num = (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) & - AMCGCR_CG1NC_MASK; + uint32_t cnt_num = read_amcgcr_cg1nc(); VERBOSE("%s%u. %s%u\n", "Number of AMU Group 1 Counters ", cnt_num, "Requested number ", AMU_GROUP1_NR_COUNTERS); @@ -74,26 +152,23 @@ void amu_enable(bool el2_unused) #endif if (el2_unused) { - uint64_t v; /* * Non-secure access from EL0 or EL1 to the Activity Monitor * registers do not trap to EL2. */ - v = read_hcptr(); - v &= ~TAM_BIT; - write_hcptr(v); + write_hcptr_tam(0U); } /* Enable group 0 counters */ - write_amcntenset0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS /* Enable group 1 counters */ - write_amcntenset1(AMU_GROUP1_COUNTERS_MASK); + write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); #endif /* Initialize FEAT_AMUv1p1 features if present. */ - if (amu_get_version() < ID_PFR0_AMU_V1P1) { + if (!amu_v1p1_supported()) { return; } @@ -106,16 +181,16 @@ void amu_enable(bool el2_unused) * mapped view are unaffected. */ VERBOSE("AMU group 1 counter access restricted.\n"); - write_amcr(read_amcr() | AMCR_CG1RZ_BIT); + write_amcr_cg1rz(1U); #else - write_amcr(read_amcr() & ~AMCR_CG1RZ_BIT); + write_amcr_cg1rz(0U); #endif } /* Read the group 0 counter identified by the given `idx`. */ static uint64_t amu_group0_cnt_read(unsigned int idx) { - assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); return amu_group0_cnt_read_internal(idx); @@ -124,7 +199,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx) /* Write the group 0 counter identified by the given `idx` with `val` */ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); amu_group0_cnt_write_internal(idx, val); @@ -135,7 +210,7 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) /* Read the group 1 counter identified by the given `idx` */ static uint64_t amu_group1_cnt_read(unsigned int idx) { - assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); @@ -145,7 +220,7 @@ static uint64_t amu_group1_cnt_read(unsigned int idx) /* Write the group 1 counter identified by the given `idx` with `val` */ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() != ID_PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); @@ -159,7 +234,7 @@ static void *amu_context_save(const void *arg) struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; unsigned int i; - if (amu_get_version() == ID_PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return (void *)-1; } @@ -169,19 +244,19 @@ static void *amu_context_save(const void *arg) } #endif /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK); + assert(read_amcntenset0_px() == AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK); + assert(read_amcntenset1_px() == AMU_GROUP1_COUNTERS_MASK); #endif /* * Disable group 0/1 counters to avoid other observers like SCP sampling * counter values from the future via the memory mapped view. */ - write_amcntenclr0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenclr0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS - write_amcntenclr1(AMU_GROUP1_COUNTERS_MASK); + write_amcntenclr1_px(AMU_GROUP1_COUNTERS_MASK); #endif isb(); @@ -206,20 +281,20 @@ static void *amu_context_restore(const void *arg) struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; unsigned int i; - if (amu_get_version() == ID_PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return (void *)-1; } #if AMU_GROUP1_NR_COUNTERS - if (!amu_group1_supported()) { + if (amu_group1_supported()) { return (void *)-1; } #endif /* Counters were disabled in `amu_context_save()` */ - assert(read_amcntenset0_el0() == 0U); + assert(read_amcntenset0_px() == 0U); #if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0() == 0U); + assert(read_amcntenset1_px() == 0U); #endif /* Restore all group 0 counters */ @@ -228,7 +303,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 0 counter configuration */ - write_amcntenset0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS /* Restore group 1 counters */ @@ -239,7 +314,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 1 counter configuration */ - write_amcntenset1(AMU_GROUP1_COUNTERS_MASK); + write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); #endif return (void *)0; diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 97eb1e366..d346174f7 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -19,26 +20,130 @@ static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; -/* - * Get AMU version value from aa64pfr0. - * Return values - * ID_AA64PFR0_AMU_V1: FEAT_AMUv1 supported (introduced in ARM v8.4) - * ID_AA64PFR0_AMU_V1P1: FEAT_AMUv1p1 supported (introduced in ARM v8.6) - * ID_AA64PFR0_AMU_NOT_SUPPORTED: not supported - */ -static unsigned int amu_get_version(void) +static inline __unused uint64_t read_id_aa64pfr0_el1_amu(void) { - return (unsigned int)(read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & + return (read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT) & ID_AA64PFR0_AMU_MASK; } -#if AMU_GROUP1_NR_COUNTERS -/* Check if group 1 counters is implemented */ -static bool amu_group1_supported(void) +static inline __unused uint64_t read_hcr_el2_amvoffen(void) +{ + return (read_hcr_el2() & HCR_AMVOFFEN_BIT) >> + HCR_AMVOFFEN_SHIFT; +} + +static inline __unused void write_cptr_el2_tam(uint64_t value) +{ + write_cptr_el2((read_cptr_el2() & ~CPTR_EL2_TAM_BIT) | + ((value << CPTR_EL2_TAM_SHIFT) & CPTR_EL2_TAM_BIT)); +} + +static inline __unused void write_cptr_el3_tam(cpu_context_t *ctx, uint64_t tam) +{ + uint64_t value = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3); + + value &= ~TAM_BIT; + value |= (tam << TAM_SHIFT) & TAM_BIT; + + write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, value); +} + +static inline __unused void write_hcr_el2_amvoffen(uint64_t value) +{ + write_hcr_el2((read_hcr_el2() & ~HCR_AMVOFFEN_BIT) | + ((value << HCR_AMVOFFEN_SHIFT) & HCR_AMVOFFEN_BIT)); +} + +static inline __unused void write_amcr_el0_cg1rz(uint64_t value) +{ + write_amcr_el0((read_amcr_el0() & ~AMCR_CG1RZ_BIT) | + ((value << AMCR_CG1RZ_SHIFT) & AMCR_CG1RZ_BIT)); +} + +static inline __unused uint64_t read_amcfgr_el0_ncg(void) +{ + return (read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT) & + AMCFGR_EL0_NCG_MASK; +} + +static inline __unused uint64_t read_amcg1idr_el0_voff(void) { - uint64_t features = read_amcfgr_el0() >> AMCFGR_EL0_NCG_SHIFT; + return (read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) & + AMCG1IDR_VOFF_MASK; +} + +static inline __unused uint64_t read_amcgcr_el0_cg1nc(void) +{ + return (read_amcgcr_el0() >> AMCGCR_EL0_CG1NC_SHIFT) & + AMCGCR_EL0_CG1NC_MASK; +} - return (features & AMCFGR_EL0_NCG_MASK) == 1U; +static inline __unused uint64_t read_amcntenset0_el0_px(void) +{ + return (read_amcntenset0_el0() >> AMCNTENSET0_EL0_Pn_SHIFT) & + AMCNTENSET0_EL0_Pn_MASK; +} + +static inline __unused uint64_t read_amcntenset1_el0_px(void) +{ + return (read_amcntenset1_el0() >> AMCNTENSET1_EL0_Pn_SHIFT) & + AMCNTENSET1_EL0_Pn_MASK; +} + +static inline __unused void write_amcntenset0_el0_px(uint64_t px) +{ + uint64_t value = read_amcntenset0_el0(); + + value &= ~AMCNTENSET0_EL0_Pn_MASK; + value |= (px << AMCNTENSET0_EL0_Pn_SHIFT) & AMCNTENSET0_EL0_Pn_MASK; + + write_amcntenset0_el0(value); +} + +static inline __unused void write_amcntenset1_el0_px(uint64_t px) +{ + uint64_t value = read_amcntenset1_el0(); + + value &= ~AMCNTENSET1_EL0_Pn_MASK; + value |= (px << AMCNTENSET1_EL0_Pn_SHIFT) & AMCNTENSET1_EL0_Pn_MASK; + + write_amcntenset1_el0(value); +} + +static inline __unused void write_amcntenclr0_el0_px(uint64_t px) +{ + uint64_t value = read_amcntenclr0_el0(); + + value &= ~AMCNTENCLR0_EL0_Pn_MASK; + value |= (px << AMCNTENCLR0_EL0_Pn_SHIFT) & AMCNTENCLR0_EL0_Pn_MASK; + + write_amcntenclr0_el0(value); +} + +static inline __unused void write_amcntenclr1_el0_px(uint64_t px) +{ + uint64_t value = read_amcntenclr1_el0(); + + value &= ~AMCNTENCLR1_EL0_Pn_MASK; + value |= (px << AMCNTENCLR1_EL0_Pn_SHIFT) & AMCNTENCLR1_EL0_Pn_MASK; + + write_amcntenclr1_el0(value); +} + +static bool amu_supported(void) +{ + return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1; +} + +static bool amu_v1p1_supported(void) +{ + return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1P1; +} + +#if ENABLE_AMU_AUXILIARY_COUNTERS +static bool amu_group1_supported(void) +{ + return read_amcfgr_el0_ncg() > 0U; } #endif @@ -48,10 +153,7 @@ static bool amu_group1_supported(void) */ void amu_enable(bool el2_unused, cpu_context_t *ctx) { - uint64_t v; - unsigned int amu_version = amu_get_version(); - - if (amu_version == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return; } @@ -63,8 +165,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) } /* Check number of group 1 counters */ - uint64_t cnt_num = (read_amcgcr_el0() >> AMCGCR_EL0_CG1NC_SHIFT) & - AMCGCR_EL0_CG1NC_MASK; + uint64_t cnt_num = read_amcgcr_el0_cg1nc(); VERBOSE("%s%llu. %s%u\n", "Number of AMU Group 1 Counters ", cnt_num, "Requested number ", AMU_GROUP1_NR_COUNTERS); @@ -82,9 +183,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) * CPTR_EL2.TAM: Set to zero so any accesses to * the Activity Monitor registers do not trap to EL2. */ - v = read_cptr_el2(); - v &= ~CPTR_EL2_TAM_BIT; - write_cptr_el2(v); + write_cptr_el2_tam(0U); } /* @@ -92,26 +191,24 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) * in 'ctx'. Set CPTR_EL3.TAM to zero so that any accesses to * the Activity Monitor registers do not trap to EL3. */ - v = read_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3); - v &= ~TAM_BIT; - write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, v); + write_cptr_el3_tam(ctx, 0U); /* Enable group 0 counters */ - write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS /* Enable group 1 counters */ - write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK); + write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); #endif /* Initialize FEAT_AMUv1p1 features if present. */ - if (amu_version < ID_AA64PFR0_AMU_V1P1) { + if (!amu_v1p1_supported()) { return; } if (el2_unused) { /* Make sure virtual offsets are disabled if EL2 not used. */ - write_hcr_el2(read_hcr_el2() & ~HCR_AMVOFFEN_BIT); + write_hcr_el2_amvoffen(0U); } #if AMU_RESTRICT_COUNTERS @@ -123,16 +220,16 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) * mapped view are unaffected. */ VERBOSE("AMU group 1 counter access restricted.\n"); - write_amcr_el0(read_amcr_el0() | AMCR_CG1RZ_BIT); + write_amcr_el0_cg1rz(1U); #else - write_amcr_el0(read_amcr_el0() & ~AMCR_CG1RZ_BIT); + write_amcr_el0_cg1rz(0U); #endif } /* Read the group 0 counter identified by the given `idx`. */ static uint64_t amu_group0_cnt_read(unsigned int idx) { - assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); return amu_group0_cnt_read_internal(idx); @@ -141,7 +238,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx) /* Write the group 0 counter identified by the given `idx` with `val` */ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); amu_group0_cnt_write_internal(idx, val); @@ -156,7 +253,7 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) */ static uint64_t amu_group0_voffset_read(unsigned int idx) { - assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); + assert(amu_v1p1_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); assert(idx != 1U); @@ -171,7 +268,7 @@ static uint64_t amu_group0_voffset_read(unsigned int idx) */ static void amu_group0_voffset_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); + assert(amu_v1p1_supported()); assert(idx < AMU_GROUP0_NR_COUNTERS); assert(idx != 1U); @@ -183,7 +280,7 @@ static void amu_group0_voffset_write(unsigned int idx, uint64_t val) /* Read the group 1 counter identified by the given `idx` */ static uint64_t amu_group1_cnt_read(unsigned int idx) { - assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); @@ -193,7 +290,7 @@ static uint64_t amu_group1_cnt_read(unsigned int idx) /* Write the group 1 counter identified by the given `idx` with `val` */ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() != ID_AA64PFR0_AMU_NOT_SUPPORTED); + assert(amu_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); @@ -208,11 +305,10 @@ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) */ static uint64_t amu_group1_voffset_read(unsigned int idx) { - assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); + assert(amu_v1p1_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); - assert(((read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) & - (1ULL << idx)) != 0ULL); + assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U); return amu_group1_voffset_read_internal(idx); } @@ -224,11 +320,10 @@ static uint64_t amu_group1_voffset_read(unsigned int idx) */ static void amu_group1_voffset_write(unsigned int idx, uint64_t val) { - assert(amu_get_version() >= ID_AA64PFR0_AMU_V1P1); + assert(amu_v1p1_supported()); assert(amu_group1_supported()); assert(idx < AMU_GROUP1_NR_COUNTERS); - assert(((read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) & - (1ULL << idx)) != 0ULL); + assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U); amu_group1_voffset_write_internal(idx, val); isb(); @@ -240,7 +335,7 @@ static void *amu_context_save(const void *arg) struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; unsigned int i; - if (amu_get_version() == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return (void *)-1; } @@ -250,19 +345,19 @@ static void *amu_context_save(const void *arg) } #endif /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_el0() == AMU_GROUP0_COUNTERS_MASK); + assert(read_amcntenset0_el0_px() == AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0() == AMU_GROUP1_COUNTERS_MASK); + assert(read_amcntenset1_el0_px() == AMU_GROUP1_COUNTERS_MASK); #endif /* * Disable group 0/1 counters to avoid other observers like SCP sampling * counter values from the future via the memory mapped view. */ - write_amcntenclr0_el0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenclr0_el0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS - write_amcntenclr1_el0(AMU_GROUP1_COUNTERS_MASK); + write_amcntenclr1_el0_px(AMU_GROUP1_COUNTERS_MASK); #endif isb(); @@ -272,8 +367,7 @@ static void *amu_context_save(const void *arg) } /* Save group 0 virtual offsets if supported and enabled. */ - if ((amu_get_version() >= ID_AA64PFR0_AMU_V1P1) && - ((read_hcr_el2() & HCR_AMVOFFEN_BIT) != 0ULL)) { + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { /* Not using a loop because count is fixed and index 1 DNE. */ ctx->group0_voffsets[0U] = amu_group0_voffset_read(0U); ctx->group0_voffsets[1U] = amu_group0_voffset_read(2U); @@ -289,11 +383,9 @@ static void *amu_context_save(const void *arg) } /* Save group 1 virtual offsets if supported and enabled. */ - if ((amu_get_version() >= ID_AA64PFR0_AMU_V1P1) && - ((read_hcr_el2() & HCR_AMVOFFEN_BIT) != 0ULL)) { - u_register_t amcg1idr = read_amcg1idr_el0() >> - AMCG1IDR_VOFF_SHIFT; - amcg1idr = amcg1idr & AMU_GROUP1_COUNTERS_MASK; + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { + uint64_t amcg1idr = read_amcg1idr_el0_voff() & + AMU_GROUP1_COUNTERS_MASK; for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { if (((amcg1idr >> i) & 1ULL) != 0ULL) { @@ -311,7 +403,7 @@ static void *amu_context_restore(const void *arg) struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; unsigned int i; - if (amu_get_version() == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + if (!amu_supported()) { return (void *)-1; } @@ -321,10 +413,10 @@ static void *amu_context_restore(const void *arg) } #endif /* Counters were disabled in `amu_context_save()` */ - assert(read_amcntenset0_el0() == 0U); + assert(read_amcntenset0_el0_px() == 0U); #if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0() == 0U); + assert(read_amcntenset1_el0_px() == 0U); #endif /* Restore all group 0 counters */ @@ -333,8 +425,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 0 virtual offsets if supported and enabled. */ - if ((amu_get_version() >= ID_AA64PFR0_AMU_V1P1) && - ((read_hcr_el2() & HCR_AMVOFFEN_BIT) != 0ULL)) { + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { /* Not using a loop because count is fixed and index 1 DNE. */ amu_group0_voffset_write(0U, ctx->group0_voffsets[0U]); amu_group0_voffset_write(2U, ctx->group0_voffsets[1U]); @@ -342,7 +433,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 0 counter configuration */ - write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); #if AMU_GROUP1_NR_COUNTERS /* Restore group 1 counters */ @@ -353,11 +444,9 @@ static void *amu_context_restore(const void *arg) } /* Restore group 1 virtual offsets if supported and enabled. */ - if ((amu_get_version() >= ID_AA64PFR0_AMU_V1P1) && - ((read_hcr_el2() & HCR_AMVOFFEN_BIT) != 0ULL)) { - u_register_t amcg1idr = read_amcg1idr_el0() >> - AMCG1IDR_VOFF_SHIFT; - amcg1idr = amcg1idr & AMU_GROUP1_COUNTERS_MASK; + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { + uint64_t amcg1idr = read_amcg1idr_el0_voff() & + AMU_GROUP1_COUNTERS_MASK; for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { if (((amcg1idr >> i) & 1ULL) != 0ULL) { @@ -368,7 +457,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 1 counter configuration */ - write_amcntenset1_el0(AMU_GROUP1_COUNTERS_MASK); + write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); #endif return (void *)0; -- cgit v1.2.3 From 1fd685a74dd33c9c26a0ec0e82e7a5a378461362 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 25 May 2021 10:42:56 +0100 Subject: refactor(amu): conditionally compile auxiliary counter support This change reduces preprocessor dependencies on the `AMU_GROUP1_NR_COUNTERS` and `AMU_GROUP1_COUNTERS_MASK` definitions, as these values will eventually be discovered dynamically. In their stead, we introduce the `ENABLE_AMU_AUXILIARY_COUNTERS` build option, which will enable support for dynamically detecting and enabling auxiliary AMU counters. This substantially reduces the amount of memory used by platforms that know ahead of time that they do not have any auxiliary AMU counters. Change-Id: I3d998aff44ed5489af4857e337e97634d06e3ea1 Signed-off-by: Chris Kay --- Makefile | 2 + docs/getting_started/build-options.rst | 5 +- include/lib/extensions/amu_private.h | 8 +- lib/extensions/amu/aarch32/amu.c | 117 +++++++++++++---------- lib/extensions/amu/aarch32/amu_helpers.S | 2 + lib/extensions/amu/aarch64/amu.c | 154 ++++++++++++++++++------------- lib/extensions/amu/aarch64/amu_helpers.S | 4 + make_helpers/defaults.mk | 1 + 8 files changed, 179 insertions(+), 114 deletions(-) diff --git a/Makefile b/Makefile index 814f98b5a..3aa0f9c9a 100644 --- a/Makefile +++ b/Makefile @@ -955,6 +955,7 @@ $(eval $(call assert_booleans,\ DYN_DISABLE_AUTH \ EL3_EXCEPTION_HANDLING \ ENABLE_AMU \ + ENABLE_AMU_AUXILIARY_COUNTERS \ AMU_RESTRICT_COUNTERS \ ENABLE_ASSERTIONS \ ENABLE_MPAM_FOR_LOWER_ELS \ @@ -1056,6 +1057,7 @@ $(eval $(call add_defines,\ DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT} \ DISABLE_MTPMU \ ENABLE_AMU \ + ENABLE_AMU_AUXILIARY_COUNTERS \ AMU_RESTRICT_COUNTERS \ ENABLE_ASSERTIONS \ ENABLE_BTI \ diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 1259881ed..f9999e108 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -220,6 +220,10 @@ Common build options v8.2 implementations also implement an AMU and this option can be used to enable this feature on those systems as well. Default is 0. +- ``ENABLE_AMU_AUXILIARY_COUNTERS``: Enables support for AMU auxiliary counters + (also known as group 1 counters). These are implementation-defined counters, + and as such require additional platform configuration. Default is 0. + - ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()`` are compiled out. For debug builds, this option defaults to 1, and calls to ``assert()`` are left in place. For release builds, this option defaults to 0 @@ -918,4 +922,3 @@ Firmware update options .. _DEN0115: https://developer.arm.com/docs/den0115/latest .. _PSA FW update specification: https://developer.arm.com/documentation/den0118/a/ - diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h index 9fe16441e..db44e6471 100644 --- a/include/lib/extensions/amu_private.h +++ b/include/lib/extensions/amu_private.h @@ -19,6 +19,7 @@ #define AMU_GROUP0_COUNTERS_MASK U(0xf) #define AMU_GROUP0_NR_COUNTERS U(4) +#if ENABLE_AMU_AUXILIARY_COUNTERS #define AMU_GROUP1_COUNTERS_MASK U(0) /* Calculate number of group 1 counters */ @@ -59,6 +60,7 @@ #endif CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); +#endif struct amu_ctx { uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; @@ -67,7 +69,7 @@ struct amu_ctx { uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1]; #endif -#if AMU_GROUP1_NR_COUNTERS +#if ENABLE_AMU_AUXILIARY_COUNTERS uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; #if __aarch64__ uint64_t group1_voffsets[AMU_GROUP1_NR_COUNTERS]; @@ -78,16 +80,20 @@ struct amu_ctx { uint64_t amu_group0_cnt_read_internal(unsigned int idx); void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val); +#if ENABLE_AMU_AUXILIARY_COUNTERS uint64_t amu_group1_cnt_read_internal(unsigned int idx); void amu_group1_cnt_write_internal(unsigned int idx, uint64_t val); void amu_group1_set_evtype_internal(unsigned int idx, unsigned int val); +#endif #if __aarch64__ uint64_t amu_group0_voffset_read_internal(unsigned int idx); void amu_group0_voffset_write_internal(unsigned int idx, uint64_t val); +#if ENABLE_AMU_AUXILIARY_COUNTERS uint64_t amu_group1_voffset_read_internal(unsigned int idx); void amu_group1_voffset_write_internal(unsigned int idx, uint64_t val); #endif +#endif #endif /* AMU_PRIVATE_H */ diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 2fc35094f..d192a897d 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -130,24 +130,27 @@ void amu_enable(bool el2_unused) return; } -#if AMU_GROUP1_NR_COUNTERS - /* Check and set presence of group 1 counters */ - if (!amu_group1_supported()) { - ERROR("AMU Counter Group 1 is not implemented\n"); - panic(); - } +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Check and set presence of group 1 counters */ + if (!amu_group1_supported()) { + ERROR("AMU Counter Group 1 is not implemented\n"); + panic(); + } + + /* Check number of group 1 counters */ + uint32_t cnt_num = read_amcgcr_cg1nc(); - /* Check number of group 1 counters */ - uint32_t cnt_num = read_amcgcr_cg1nc(); - VERBOSE("%s%u. %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - - if (cnt_num < AMU_GROUP1_NR_COUNTERS) { - ERROR("%s%u is less than %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - panic(); + VERBOSE("%s%u. %s%u\n", + "Number of AMU Group 1 Counters ", cnt_num, + "Requested number ", AMU_GROUP1_NR_COUNTERS); + + if (cnt_num < AMU_GROUP1_NR_COUNTERS) { + ERROR("%s%u is less than %s%u\n", + "Number of AMU Group 1 Counters ", cnt_num, + "Requested number ", AMU_GROUP1_NR_COUNTERS); + panic(); + } } #endif @@ -162,9 +165,11 @@ void amu_enable(bool el2_unused) /* Enable group 0 counters */ write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - /* Enable group 1 counters */ - write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Enable group 1 counters */ + write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); + } #endif /* Initialize FEAT_AMUv1p1 features if present. */ @@ -206,7 +211,7 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) isb(); } -#if AMU_GROUP1_NR_COUNTERS +#if ENABLE_AMU_AUXILIARY_COUNTERS /* Read the group 1 counter identified by the given `idx` */ static uint64_t amu_group1_cnt_read(unsigned int idx) { @@ -227,7 +232,7 @@ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) amu_group1_cnt_write_internal(idx, val); isb(); } -#endif /* AMU_GROUP1_NR_COUNTERS */ +#endif static void *amu_context_save(const void *arg) { @@ -238,16 +243,21 @@ static void *amu_context_save(const void *arg) return (void *)-1; } -#if AMU_GROUP1_NR_COUNTERS - if (!amu_group1_supported()) { - return (void *)-1; +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (!amu_group1_supported()) { + return (void *)-1; + } } #endif + /* Assert that group 0/1 counter configuration is what we expect */ assert(read_amcntenset0_px() == AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_px() == AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + assert(read_amcntenset1_px() == AMU_GROUP1_COUNTERS_MASK); + } #endif /* * Disable group 0/1 counters to avoid other observers like SCP sampling @@ -255,9 +265,12 @@ static void *amu_context_save(const void *arg) */ write_amcntenclr0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - write_amcntenclr1_px(AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + write_amcntenclr1_px(AMU_GROUP1_COUNTERS_MASK); + } #endif + isb(); /* Save all group 0 counters */ @@ -265,14 +278,17 @@ static void *amu_context_save(const void *arg) ctx->group0_cnts[i] = amu_group0_cnt_read(i); } -#if AMU_GROUP1_NR_COUNTERS - /* Save group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { - ctx->group1_cnts[i] = amu_group1_cnt_read(i); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Save group 1 counters */ + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { + ctx->group1_cnts[i] = amu_group1_cnt_read(i); + } } } #endif + return (void *)0; } @@ -285,16 +301,21 @@ static void *amu_context_restore(const void *arg) return (void *)-1; } -#if AMU_GROUP1_NR_COUNTERS - if (amu_group1_supported()) { - return (void *)-1; +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (!amu_group1_supported()) { + return (void *)-1; + } } #endif + /* Counters were disabled in `amu_context_save()` */ assert(read_amcntenset0_px() == 0U); -#if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_px() == 0U); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + assert(read_amcntenset1_px() == 0U); + } #endif /* Restore all group 0 counters */ @@ -305,16 +326,18 @@ static void *amu_context_restore(const void *arg) /* Restore group 0 counter configuration */ write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - /* Restore group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { - amu_group1_cnt_write(i, ctx->group1_cnts[i]); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Restore group 1 counters */ + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { + amu_group1_cnt_write(i, ctx->group1_cnts[i]); + } } - } - /* Restore group 1 counter configuration */ - write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); + /* Restore group 1 counter configuration */ + write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); + } #endif return (void *)0; diff --git a/lib/extensions/amu/aarch32/amu_helpers.S b/lib/extensions/amu/aarch32/amu_helpers.S index d387341f7..8ac76785a 100644 --- a/lib/extensions/amu/aarch32/amu_helpers.S +++ b/lib/extensions/amu/aarch32/amu_helpers.S @@ -84,6 +84,7 @@ func amu_group0_cnt_write_internal bx lr endfunc amu_group0_cnt_write_internal +#if ENABLE_AMU_AUXILIARY_COUNTERS /* * uint64_t amu_group1_cnt_read_internal(int idx); * @@ -267,3 +268,4 @@ func amu_group1_set_evtype_internal stcopr r1, AMEVTYPER1F /* index 15 */ bx lr endfunc amu_group1_set_evtype_internal +#endif diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index d346174f7..b2a90ee8c 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -157,24 +157,27 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) return; } -#if AMU_GROUP1_NR_COUNTERS - /* Check and set presence of group 1 counters */ - if (!amu_group1_supported()) { - ERROR("AMU Counter Group 1 is not implemented\n"); - panic(); - } +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Check and set presence of group 1 counters */ + if (!amu_group1_supported()) { + ERROR("AMU Counter Group 1 is not implemented\n"); + panic(); + } - /* Check number of group 1 counters */ - uint64_t cnt_num = read_amcgcr_el0_cg1nc(); - VERBOSE("%s%llu. %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - - if (cnt_num < AMU_GROUP1_NR_COUNTERS) { - ERROR("%s%llu is less than %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - panic(); + /* Check number of group 1 counters */ + uint64_t cnt_num = read_amcgcr_el0_cg1nc(); + + VERBOSE("%s%llu. %s%u\n", + "Number of AMU Group 1 Counters ", cnt_num, + "Requested number ", AMU_GROUP1_NR_COUNTERS); + + if (cnt_num < AMU_GROUP1_NR_COUNTERS) { + ERROR("%s%llu is less than %s%u\n", + "Number of AMU Group 1 Counters ", cnt_num, + "Requested number ", AMU_GROUP1_NR_COUNTERS); + panic(); + } } #endif @@ -196,9 +199,11 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) /* Enable group 0 counters */ write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - /* Enable group 1 counters */ - write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Enable group 1 counters */ + write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); + } #endif /* Initialize FEAT_AMUv1p1 features if present. */ @@ -276,7 +281,7 @@ static void amu_group0_voffset_write(unsigned int idx, uint64_t val) isb(); } -#if AMU_GROUP1_NR_COUNTERS +#if ENABLE_AMU_AUXILIARY_COUNTERS /* Read the group 1 counter identified by the given `idx` */ static uint64_t amu_group1_cnt_read(unsigned int idx) { @@ -328,7 +333,7 @@ static void amu_group1_voffset_write(unsigned int idx, uint64_t val) amu_group1_voffset_write_internal(idx, val); isb(); } -#endif /* AMU_GROUP1_NR_COUNTERS */ +#endif static void *amu_context_save(const void *arg) { @@ -339,26 +344,35 @@ static void *amu_context_save(const void *arg) return (void *)-1; } -#if AMU_GROUP1_NR_COUNTERS - if (!amu_group1_supported()) { - return (void *)-1; +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (!amu_group1_supported()) { + return (void *)-1; + } } #endif + /* Assert that group 0/1 counter configuration is what we expect */ assert(read_amcntenset0_el0_px() == AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0_px() == AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + assert(read_amcntenset1_el0_px() == AMU_GROUP1_COUNTERS_MASK); + } #endif + /* * Disable group 0/1 counters to avoid other observers like SCP sampling * counter values from the future via the memory mapped view. */ write_amcntenclr0_el0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - write_amcntenclr1_el0_px(AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + write_amcntenclr1_el0_px(AMU_GROUP1_COUNTERS_MASK); + } #endif + isb(); /* Save all group 0 counters */ @@ -374,27 +388,30 @@ static void *amu_context_save(const void *arg) ctx->group0_voffsets[2U] = amu_group0_voffset_read(3U); } -#if AMU_GROUP1_NR_COUNTERS - /* Save group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { - ctx->group1_cnts[i] = amu_group1_cnt_read(i); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Save group 1 counters */ + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { + ctx->group1_cnts[i] = amu_group1_cnt_read(i); + } } - } - /* Save group 1 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - uint64_t amcg1idr = read_amcg1idr_el0_voff() & - AMU_GROUP1_COUNTERS_MASK; + /* Save group 1 virtual offsets if supported and enabled. */ + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { + uint64_t amcg1idr = read_amcg1idr_el0_voff() & + AMU_GROUP1_COUNTERS_MASK; - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if (((amcg1idr >> i) & 1ULL) != 0ULL) { - ctx->group1_voffsets[i] = - amu_group1_voffset_read(i); + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if (((amcg1idr >> i) & 1ULL) != 0ULL) { + ctx->group1_voffsets[i] = + amu_group1_voffset_read(i); + } } } } #endif + return (void *)0; } @@ -407,16 +424,21 @@ static void *amu_context_restore(const void *arg) return (void *)-1; } -#if AMU_GROUP1_NR_COUNTERS - if (!amu_group1_supported()) { - return (void *)-1; +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (!amu_group1_supported()) { + return (void *)-1; + } } #endif + /* Counters were disabled in `amu_context_save()` */ assert(read_amcntenset0_el0_px() == 0U); -#if AMU_GROUP1_NR_COUNTERS - assert(read_amcntenset1_el0_px() == 0U); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + assert(read_amcntenset1_el0_px() == 0U); + } #endif /* Restore all group 0 counters */ @@ -435,29 +457,31 @@ static void *amu_context_restore(const void *arg) /* Restore group 0 counter configuration */ write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); -#if AMU_GROUP1_NR_COUNTERS - /* Restore group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { - amu_group1_cnt_write(i, ctx->group1_cnts[i]); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (AMU_GROUP1_NR_COUNTERS > 0U) { + /* Restore group 1 counters */ + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { + amu_group1_cnt_write(i, ctx->group1_cnts[i]); + } } - } - /* Restore group 1 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - uint64_t amcg1idr = read_amcg1idr_el0_voff() & - AMU_GROUP1_COUNTERS_MASK; + /* Restore group 1 virtual offsets if supported and enabled. */ + if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { + uint64_t amcg1idr = read_amcg1idr_el0_voff() & + AMU_GROUP1_COUNTERS_MASK; - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { - if (((amcg1idr >> i) & 1ULL) != 0ULL) { - amu_group1_voffset_write(i, - ctx->group1_voffsets[i]); + for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + if (((amcg1idr >> i) & 1ULL) != 0ULL) { + amu_group1_voffset_write(i, + ctx->group1_voffsets[i]); + } } } - } - /* Restore group 1 counter configuration */ - write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); + /* Restore group 1 counter configuration */ + write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); + } #endif return (void *)0; diff --git a/lib/extensions/amu/aarch64/amu_helpers.S b/lib/extensions/amu/aarch64/amu_helpers.S index 9989abdeb..0f6d799ea 100644 --- a/lib/extensions/amu/aarch64/amu_helpers.S +++ b/lib/extensions/amu/aarch64/amu_helpers.S @@ -83,6 +83,7 @@ func amu_group0_cnt_write_internal write AMEVCNTR03_EL0 /* index 3 */ endfunc amu_group0_cnt_write_internal +#if ENABLE_AMU_AUXILIARY_COUNTERS /* * uint64_t amu_group1_cnt_read_internal(int idx); * @@ -217,6 +218,7 @@ func amu_group1_set_evtype_internal write AMEVTYPER1E_EL0 /* index 14 */ write AMEVTYPER1F_EL0 /* index 15 */ endfunc amu_group1_set_evtype_internal +#endif /* * Accessor functions for virtual offset registers added with FEAT_AMUv1p1 @@ -297,6 +299,7 @@ func amu_group0_voffset_write_internal write AMEVCNTVOFF03_EL2 /* index 3 */ endfunc amu_group0_voffset_write_internal +#if ENABLE_AMU_AUXILIARY_COUNTERS /* * uint64_t amu_group1_voffset_read_internal(int idx); * @@ -383,3 +386,4 @@ func amu_group1_voffset_write_internal write AMEVCNTVOFF1E_EL2 /* index 14 */ write AMEVCNTVOFF1F_EL2 /* index 15 */ endfunc amu_group1_voffset_write_internal +#endif diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 819c53686..4344cf8ba 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -306,6 +306,7 @@ endif CTX_INCLUDE_MTE_REGS := 0 ENABLE_AMU := 0 +ENABLE_AMU_AUXILIARY_COUNTERS := 0 AMU_RESTRICT_COUNTERS := 0 # By default, enable Scalable Vector Extension if implemented only for Non-secure -- cgit v1.2.3 From 81e2ff1f364fdf18e086f690eb3715bc89307592 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 25 May 2021 12:33:18 +0100 Subject: refactor(amu): detect architected counters at runtime This change removes the `AMU_GROUP0_COUNTERS_MASK` and `AMU_GROUP0_MAX_COUNTERS` preprocessor definitions, instead retrieving the number of group 0 counters dynamically through `AMCGCR_EL0.CG0NC`. Change-Id: I70e39c30fbd5df89b214276fac79cc8758a89f72 Signed-off-by: Chris Kay --- include/arch/aarch32/arch.h | 2 ++ include/arch/aarch64/arch.h | 2 ++ include/lib/extensions/amu_private.h | 8 +++----- lib/extensions/amu/aarch32/amu.c | 23 +++++++++++++++-------- lib/extensions/amu/aarch64/amu.c | 27 +++++++++++++++++---------- 5 files changed, 39 insertions(+), 23 deletions(-) diff --git a/include/arch/aarch32/arch.h b/include/arch/aarch32/arch.h index 59680b7c6..a1bd94291 100644 --- a/include/arch/aarch32/arch.h +++ b/include/arch/aarch32/arch.h @@ -755,6 +755,8 @@ #define AMCFGR_N_MASK U(0xff) /* AMCGCR definitions */ +#define AMCGCR_CG0NC_SHIFT U(0) +#define AMCGCR_CG0NC_MASK U(0xff) #define AMCGCR_CG1NC_SHIFT U(8) #define AMCGCR_CG1NC_MASK U(0xff) diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index a72087e8f..8b362f1cc 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1069,6 +1069,8 @@ #define AMCFGR_EL0_N_MASK U(0xff) /* AMCGCR_EL0 definitions */ +#define AMCGCR_EL0_CG0NC_SHIFT U(0) +#define AMCGCR_EL0_CG0NC_MASK U(0xff) #define AMCGCR_EL0_CG1NC_SHIFT U(8) #define AMCGCR_EL0_CG1NC_MASK U(0xff) diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h index db44e6471..9b4c29c87 100644 --- a/include/lib/extensions/amu_private.h +++ b/include/lib/extensions/amu_private.h @@ -15,9 +15,7 @@ #include -/* All group 0 counters */ -#define AMU_GROUP0_COUNTERS_MASK U(0xf) -#define AMU_GROUP0_NR_COUNTERS U(4) +#define AMU_GROUP0_MAX_COUNTERS U(16) #if ENABLE_AMU_AUXILIARY_COUNTERS #define AMU_GROUP1_COUNTERS_MASK U(0) @@ -63,10 +61,10 @@ CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); #endif struct amu_ctx { - uint64_t group0_cnts[AMU_GROUP0_NR_COUNTERS]; + uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; #if __aarch64__ /* Architected event counter 1 does not have an offset register. */ - uint64_t group0_voffsets[AMU_GROUP0_NR_COUNTERS-1]; + uint64_t group0_voffsets[AMU_GROUP0_MAX_COUNTERS-1]; #endif #if ENABLE_AMU_AUXILIARY_COUNTERS diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index d192a897d..47330863e 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -43,6 +43,12 @@ static inline __unused uint32_t read_amcfgr_ncg(void) AMCFGR_NCG_MASK; } +static inline __unused uint32_t read_amcgcr_cg0nc(void) +{ + return (read_amcgcr() >> AMCGCR_CG0NC_SHIFT) & + AMCGCR_CG0NC_MASK; +} + static inline __unused uint32_t read_amcgcr_cg1nc(void) { return (read_amcgcr() >> AMCGCR_CG1NC_SHIFT) & @@ -163,7 +169,7 @@ void amu_enable(bool el2_unused) } /* Enable group 0 counters */ - write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -196,7 +202,7 @@ void amu_enable(bool el2_unused) static uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_cg0nc()); return amu_group0_cnt_read_internal(idx); } @@ -205,7 +211,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx) static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_cg0nc()); amu_group0_cnt_write_internal(idx, val); isb(); @@ -252,7 +258,8 @@ static void *amu_context_save(const void *arg) #endif /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_px() == AMU_GROUP0_COUNTERS_MASK); + assert(read_amcntenset0_px() == + ((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U)); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -263,7 +270,7 @@ static void *amu_context_save(const void *arg) * Disable group 0/1 counters to avoid other observers like SCP sampling * counter values from the future via the memory mapped view. */ - write_amcntenclr0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenclr0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -274,7 +281,7 @@ static void *amu_context_save(const void *arg) isb(); /* Save all group 0 counters */ - for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_cg0nc(); i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); } @@ -319,12 +326,12 @@ static void *amu_context_restore(const void *arg) #endif /* Restore all group 0 counters */ - for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_cg0nc(); i++) { amu_group0_cnt_write(i, ctx->group0_cnts[i]); } /* Restore group 0 counter configuration */ - write_amcntenset0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index b2a90ee8c..129616ea9 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -66,6 +66,12 @@ static inline __unused uint64_t read_amcfgr_el0_ncg(void) AMCFGR_EL0_NCG_MASK; } +static inline uint64_t read_amcgcr_el0_cg0nc(void) +{ + return (read_amcgcr_el0() >> AMCGCR_EL0_CG0NC_SHIFT) & + AMCGCR_EL0_CG0NC_MASK; +} + static inline __unused uint64_t read_amcg1idr_el0_voff(void) { return (read_amcg1idr_el0() >> AMCG1IDR_VOFF_SHIFT) & @@ -197,7 +203,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) write_cptr_el3_tam(ctx, 0U); /* Enable group 0 counters */ - write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -235,7 +241,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) static uint64_t amu_group0_cnt_read(unsigned int idx) { assert(amu_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg0nc()); return amu_group0_cnt_read_internal(idx); } @@ -244,7 +250,7 @@ static uint64_t amu_group0_cnt_read(unsigned int idx) static void amu_group0_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg0nc()); amu_group0_cnt_write_internal(idx, val); isb(); @@ -259,7 +265,7 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) static uint64_t amu_group0_voffset_read(unsigned int idx) { assert(amu_v1p1_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg0nc()); assert(idx != 1U); return amu_group0_voffset_read_internal(idx); @@ -274,7 +280,7 @@ static uint64_t amu_group0_voffset_read(unsigned int idx) static void amu_group0_voffset_write(unsigned int idx, uint64_t val) { assert(amu_v1p1_supported()); - assert(idx < AMU_GROUP0_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg0nc()); assert(idx != 1U); amu_group0_voffset_write_internal(idx, val); @@ -353,7 +359,8 @@ static void *amu_context_save(const void *arg) #endif /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_el0_px() == AMU_GROUP0_COUNTERS_MASK); + assert(read_amcntenset0_el0_px() == + ((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U)); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -365,7 +372,7 @@ static void *amu_context_save(const void *arg) * Disable group 0/1 counters to avoid other observers like SCP sampling * counter values from the future via the memory mapped view. */ - write_amcntenclr0_el0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenclr0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { @@ -376,7 +383,7 @@ static void *amu_context_save(const void *arg) isb(); /* Save all group 0 counters */ - for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); } @@ -442,7 +449,7 @@ static void *amu_context_restore(const void *arg) #endif /* Restore all group 0 counters */ - for (i = 0U; i < AMU_GROUP0_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) { amu_group0_cnt_write(i, ctx->group0_cnts[i]); } @@ -455,7 +462,7 @@ static void *amu_context_restore(const void *arg) } /* Restore group 0 counter configuration */ - write_amcntenset0_el0_px(AMU_GROUP0_COUNTERS_MASK); + write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS if (AMU_GROUP1_NR_COUNTERS > 0U) { -- cgit v1.2.3 From 31d3cc2570dd61ac30efab030708ef32fcc987e5 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 25 May 2021 15:24:18 +0100 Subject: refactor(amu): detect auxiliary counters at runtime This change decouples the group 1 counter macros to facilitate dynamic detection at runtime. These counters remain disabled - we will add dynamic enablement of them in a later patch. Change-Id: I820d05f228d440643bdfa308d030bd51ebc0b35a Signed-off-by: Chris Kay --- include/lib/extensions/amu_private.h | 44 ++--------------------- lib/extensions/amu/aarch32/amu.c | 60 ++++++------------------------- lib/extensions/amu/aarch64/amu.c | 68 ++++++++---------------------------- 3 files changed, 27 insertions(+), 145 deletions(-) diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h index 9b4c29c87..efa6f6c44 100644 --- a/include/lib/extensions/amu_private.h +++ b/include/lib/extensions/amu_private.h @@ -16,48 +16,10 @@ #include #define AMU_GROUP0_MAX_COUNTERS U(16) +#define AMU_GROUP1_MAX_COUNTERS U(16) #if ENABLE_AMU_AUXILIARY_COUNTERS #define AMU_GROUP1_COUNTERS_MASK U(0) - -/* Calculate number of group 1 counters */ -#if (AMU_GROUP1_COUNTERS_MASK & (1 << 15)) -#define AMU_GROUP1_NR_COUNTERS 16U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 14)) -#define AMU_GROUP1_NR_COUNTERS 15U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 13)) -#define AMU_GROUP1_NR_COUNTERS 14U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 12)) -#define AMU_GROUP1_NR_COUNTERS 13U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 11)) -#define AMU_GROUP1_NR_COUNTERS 12U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 10)) -#define AMU_GROUP1_NR_COUNTERS 11U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 9)) -#define AMU_GROUP1_NR_COUNTERS 10U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 8)) -#define AMU_GROUP1_NR_COUNTERS 9U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 7)) -#define AMU_GROUP1_NR_COUNTERS 8U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 6)) -#define AMU_GROUP1_NR_COUNTERS 7U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 5)) -#define AMU_GROUP1_NR_COUNTERS 6U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 4)) -#define AMU_GROUP1_NR_COUNTERS 5U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 3)) -#define AMU_GROUP1_NR_COUNTERS 4U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 2)) -#define AMU_GROUP1_NR_COUNTERS 3U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 1)) -#define AMU_GROUP1_NR_COUNTERS 2U -#elif (AMU_GROUP1_COUNTERS_MASK & (1 << 0)) -#define AMU_GROUP1_NR_COUNTERS 1U -#else -#define AMU_GROUP1_NR_COUNTERS 0U -#endif - -CASSERT(AMU_GROUP1_COUNTERS_MASK <= 0xffff, invalid_amu_group1_counters_mask); #endif struct amu_ctx { @@ -68,9 +30,9 @@ struct amu_ctx { #endif #if ENABLE_AMU_AUXILIARY_COUNTERS - uint64_t group1_cnts[AMU_GROUP1_NR_COUNTERS]; + uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS]; #if __aarch64__ - uint64_t group1_voffsets[AMU_GROUP1_NR_COUNTERS]; + uint64_t group1_voffsets[AMU_GROUP1_MAX_COUNTERS]; #endif #endif }; diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 47330863e..89487986d 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -136,30 +136,6 @@ void amu_enable(bool el2_unused) return; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - /* Check and set presence of group 1 counters */ - if (!amu_group1_supported()) { - ERROR("AMU Counter Group 1 is not implemented\n"); - panic(); - } - - /* Check number of group 1 counters */ - uint32_t cnt_num = read_amcgcr_cg1nc(); - - VERBOSE("%s%u. %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - - if (cnt_num < AMU_GROUP1_NR_COUNTERS) { - ERROR("%s%u is less than %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - panic(); - } - } -#endif - if (el2_unused) { /* * Non-secure access from EL0 or EL1 to the Activity Monitor @@ -172,7 +148,7 @@ void amu_enable(bool el2_unused) write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Enable group 1 counters */ write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); } @@ -223,7 +199,7 @@ static uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_cg1nc()); return amu_group1_cnt_read_internal(idx); } @@ -233,7 +209,7 @@ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_cg1nc()); amu_group1_cnt_write_internal(idx, val); isb(); @@ -249,20 +225,12 @@ static void *amu_context_save(const void *arg) return (void *)-1; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - if (!amu_group1_supported()) { - return (void *)-1; - } - } -#endif - /* Assert that group 0/1 counter configuration is what we expect */ assert(read_amcntenset0_px() == ((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U)); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { assert(read_amcntenset1_px() == AMU_GROUP1_COUNTERS_MASK); } #endif @@ -273,7 +241,7 @@ static void *amu_context_save(const void *arg) write_amcntenclr0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { write_amcntenclr1_px(AMU_GROUP1_COUNTERS_MASK); } #endif @@ -286,9 +254,9 @@ static void *amu_context_save(const void *arg) } #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Save group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_cg1nc(); i++) { if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { ctx->group1_cnts[i] = amu_group1_cnt_read(i); } @@ -308,19 +276,11 @@ static void *amu_context_restore(const void *arg) return (void *)-1; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - if (!amu_group1_supported()) { - return (void *)-1; - } - } -#endif - /* Counters were disabled in `amu_context_save()` */ assert(read_amcntenset0_px() == 0U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { assert(read_amcntenset1_px() == 0U); } #endif @@ -334,9 +294,9 @@ static void *amu_context_restore(const void *arg) write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Restore group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_cg1nc(); i++) { if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { amu_group1_cnt_write(i, ctx->group1_cnts[i]); } diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 129616ea9..6bed6c3cf 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -163,30 +163,6 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) return; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - /* Check and set presence of group 1 counters */ - if (!amu_group1_supported()) { - ERROR("AMU Counter Group 1 is not implemented\n"); - panic(); - } - - /* Check number of group 1 counters */ - uint64_t cnt_num = read_amcgcr_el0_cg1nc(); - - VERBOSE("%s%llu. %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - - if (cnt_num < AMU_GROUP1_NR_COUNTERS) { - ERROR("%s%llu is less than %s%u\n", - "Number of AMU Group 1 Counters ", cnt_num, - "Requested number ", AMU_GROUP1_NR_COUNTERS); - panic(); - } - } -#endif - if (el2_unused) { /* * CPTR_EL2.TAM: Set to zero so any accesses to @@ -206,7 +182,7 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Enable group 1 counters */ write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); } @@ -293,7 +269,7 @@ static uint64_t amu_group1_cnt_read(unsigned int idx) { assert(amu_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg1nc()); return amu_group1_cnt_read_internal(idx); } @@ -303,7 +279,7 @@ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) { assert(amu_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg1nc()); amu_group1_cnt_write_internal(idx, val); isb(); @@ -318,7 +294,7 @@ static uint64_t amu_group1_voffset_read(unsigned int idx) { assert(amu_v1p1_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg1nc()); assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U); return amu_group1_voffset_read_internal(idx); @@ -333,7 +309,7 @@ static void amu_group1_voffset_write(unsigned int idx, uint64_t val) { assert(amu_v1p1_supported()); assert(amu_group1_supported()); - assert(idx < AMU_GROUP1_NR_COUNTERS); + assert(idx < read_amcgcr_el0_cg1nc()); assert((read_amcg1idr_el0_voff() & (UINT64_C(1) << idx)) != 0U); amu_group1_voffset_write_internal(idx, val); @@ -350,20 +326,12 @@ static void *amu_context_save(const void *arg) return (void *)-1; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - if (!amu_group1_supported()) { - return (void *)-1; - } - } -#endif - /* Assert that group 0/1 counter configuration is what we expect */ assert(read_amcntenset0_el0_px() == ((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U)); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { assert(read_amcntenset1_el0_px() == AMU_GROUP1_COUNTERS_MASK); } #endif @@ -375,7 +343,7 @@ static void *amu_context_save(const void *arg) write_amcntenclr0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { write_amcntenclr1_el0_px(AMU_GROUP1_COUNTERS_MASK); } #endif @@ -396,9 +364,9 @@ static void *amu_context_save(const void *arg) } #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Save group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { ctx->group1_cnts[i] = amu_group1_cnt_read(i); } @@ -409,7 +377,7 @@ static void *amu_context_save(const void *arg) uint64_t amcg1idr = read_amcg1idr_el0_voff() & AMU_GROUP1_COUNTERS_MASK; - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { if (((amcg1idr >> i) & 1ULL) != 0ULL) { ctx->group1_voffsets[i] = amu_group1_voffset_read(i); @@ -431,19 +399,11 @@ static void *amu_context_restore(const void *arg) return (void *)-1; } -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { - if (!amu_group1_supported()) { - return (void *)-1; - } - } -#endif - /* Counters were disabled in `amu_context_save()` */ assert(read_amcntenset0_el0_px() == 0U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { assert(read_amcntenset1_el0_px() == 0U); } #endif @@ -465,9 +425,9 @@ static void *amu_context_restore(const void *arg) write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (AMU_GROUP1_NR_COUNTERS > 0U) { + if (amu_group1_supported()) { /* Restore group 1 counters */ - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { amu_group1_cnt_write(i, ctx->group1_cnts[i]); } @@ -478,7 +438,7 @@ static void *amu_context_restore(const void *arg) uint64_t amcg1idr = read_amcg1idr_el0_voff() & AMU_GROUP1_COUNTERS_MASK; - for (i = 0U; i < AMU_GROUP1_NR_COUNTERS; i++) { + for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { if (((amcg1idr >> i) & 1ULL) != 0ULL) { amu_group1_voffset_write(i, ctx->group1_voffsets[i]); -- cgit v1.2.3 From e747a59be4ab8e9fa6edc7f4fb04478cd0f823c2 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Mon, 24 May 2021 20:35:26 +0100 Subject: refactor(amu): refactor enablement and context switching This change represents a general refactoring to clean up old code that has been adapted to account for changes required to enable dynamic auxiliary counters. Change-Id: Ia85e0518f3f65c765f07b34b67744fc869b9070d Signed-off-by: Chris Kay --- include/lib/extensions/amu_private.h | 59 ------- lib/extensions/amu/aarch32/amu.c | 218 +++++++++++++++-------- lib/extensions/amu/aarch64/amu.c | 325 ++++++++++++++++++++++++----------- lib/extensions/amu/amu_private.h | 38 ++++ 4 files changed, 414 insertions(+), 226 deletions(-) delete mode 100644 include/lib/extensions/amu_private.h create mode 100644 lib/extensions/amu/amu_private.h diff --git a/include/lib/extensions/amu_private.h b/include/lib/extensions/amu_private.h deleted file mode 100644 index efa6f6c44..000000000 --- a/include/lib/extensions/amu_private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AMU_PRIVATE_H -#define AMU_PRIVATE_H - -#include - -#include -#include -#include - -#include - -#define AMU_GROUP0_MAX_COUNTERS U(16) -#define AMU_GROUP1_MAX_COUNTERS U(16) - -#if ENABLE_AMU_AUXILIARY_COUNTERS -#define AMU_GROUP1_COUNTERS_MASK U(0) -#endif - -struct amu_ctx { - uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; -#if __aarch64__ - /* Architected event counter 1 does not have an offset register. */ - uint64_t group0_voffsets[AMU_GROUP0_MAX_COUNTERS-1]; -#endif - -#if ENABLE_AMU_AUXILIARY_COUNTERS - uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS]; -#if __aarch64__ - uint64_t group1_voffsets[AMU_GROUP1_MAX_COUNTERS]; -#endif -#endif -}; - -uint64_t amu_group0_cnt_read_internal(unsigned int idx); -void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val); - -#if ENABLE_AMU_AUXILIARY_COUNTERS -uint64_t amu_group1_cnt_read_internal(unsigned int idx); -void amu_group1_cnt_write_internal(unsigned int idx, uint64_t val); -void amu_group1_set_evtype_internal(unsigned int idx, unsigned int val); -#endif - -#if __aarch64__ -uint64_t amu_group0_voffset_read_internal(unsigned int idx); -void amu_group0_voffset_write_internal(unsigned int idx, uint64_t val); - -#if ENABLE_AMU_AUXILIARY_COUNTERS -uint64_t amu_group1_voffset_read_internal(unsigned int idx); -void amu_group1_voffset_write_internal(unsigned int idx, uint64_t val); -#endif -#endif - -#endif /* AMU_PRIVATE_H */ diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index 89487986d..e92b9f130 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -8,16 +8,35 @@ #include #include +#include "../amu_private.h" #include #include - #include #include -#include #include -static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; +struct amu_ctx { + uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS]; +#endif + + uint16_t group0_enable; +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint16_t group1_enable; +#endif +}; + +static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT]; + +CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS, + amu_ctx_group0_enable_cannot_represent_all_group0_counters); + +#if ENABLE_AMU_AUXILIARY_COUNTERS +CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS, + amu_ctx_group1_enable_cannot_represent_all_group1_counters); +#endif static inline __unused uint32_t read_id_pfr0_amu(void) { @@ -109,53 +128,72 @@ static inline __unused void write_amcntenclr1_px(uint32_t px) write_amcntenclr1(value); } -static bool amu_supported(void) +static __unused bool amu_supported(void) { return read_id_pfr0_amu() >= ID_PFR0_AMU_V1; } -static bool amu_v1p1_supported(void) -{ - return read_id_pfr0_amu() >= ID_PFR0_AMU_V1P1; -} - #if ENABLE_AMU_AUXILIARY_COUNTERS -static bool amu_group1_supported(void) +static __unused bool amu_group1_supported(void) { return read_amcfgr_ncg() > 0U; } #endif /* - * Enable counters. This function is meant to be invoked - * by the context management library before exiting from EL3. + * Enable counters. This function is meant to be invoked by the context + * management library before exiting from EL3. */ void amu_enable(bool el2_unused) { - if (!amu_supported()) { + uint32_t id_pfr0_amu; /* AMU version */ + + uint32_t amcfgr_ncg; /* Number of counter groups */ + uint32_t amcgcr_cg0nc; /* Number of group 0 counters */ + + uint32_t amcntenset0_px = 0x0; /* Group 0 enable mask */ + uint32_t amcntenset1_px = 0x0; /* Group 1 enable mask */ + + id_pfr0_amu = read_id_pfr0_amu(); + if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) { + /* + * If the AMU is unsupported, nothing needs to be done. + */ + return; } if (el2_unused) { /* - * Non-secure access from EL0 or EL1 to the Activity Monitor - * registers do not trap to EL2. + * HCPTR.TAM: Set to zero so any accesses to the Activity + * Monitor registers do not trap to EL2. */ write_hcptr_tam(0U); } - /* Enable group 0 counters */ - write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); + /* + * Retrieve the number of architected counters. All of these counters + * are enabled by default. + */ -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Enable group 1 counters */ - write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); + amcgcr_cg0nc = read_amcgcr_cg0nc(); + amcntenset0_px = (UINT32_C(1) << (amcgcr_cg0nc)) - 1U; + + assert(amcgcr_cg0nc <= AMU_AMCGCR_CG0NC_MAX); + + /* + * Enable the requested counters. + */ + + write_amcntenset0_px(amcntenset0_px); + + amcfgr_ncg = read_amcfgr_ncg(); + if (amcfgr_ncg > 0U) { + write_amcntenset1_px(amcntenset1_px); } -#endif /* Initialize FEAT_AMUv1p1 features if present. */ - if (!amu_v1p1_supported()) { + if (id_pfr0_amu < ID_PFR0_AMU_V1P1) { return; } @@ -218,49 +256,61 @@ static void amu_group1_cnt_write(unsigned int idx, uint64_t val) static void *amu_context_save(const void *arg) { - struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - unsigned int i; + uint32_t i; - if (!amu_supported()) { - return (void *)-1; - } + unsigned int core_pos; + struct amu_ctx *ctx; - /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_px() == - ((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U)); + uint32_t id_pfr0_amu; /* AMU version */ + uint32_t amcgcr_cg0nc; /* Number of group 0 counters */ #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - assert(read_amcntenset1_px() == AMU_GROUP1_COUNTERS_MASK); + uint32_t amcfgr_ncg; /* Number of counter groups */ + uint32_t amcgcr_cg1nc; /* Number of group 1 counters */ +#endif + + id_pfr0_amu = read_id_pfr0_amu(); + if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) { + return (void *)0; } + + core_pos = plat_my_core_pos(); + ctx = &amu_ctxs_[core_pos]; + + amcgcr_cg0nc = read_amcgcr_cg0nc(); + +#if ENABLE_AMU_AUXILIARY_COUNTERS + amcfgr_ncg = read_amcfgr_ncg(); + amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U; #endif + /* - * Disable group 0/1 counters to avoid other observers like SCP sampling - * counter values from the future via the memory mapped view. + * Disable all AMU counters. */ - write_amcntenclr0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); + + ctx->group0_enable = read_amcntenset0_px(); + write_amcntenclr0_px(ctx->group0_enable); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - write_amcntenclr1_px(AMU_GROUP1_COUNTERS_MASK); + if (amcfgr_ncg > 0U) { + ctx->group1_enable = read_amcntenset1_px(); + write_amcntenclr1_px(ctx->group1_enable); } #endif - isb(); + /* + * Save the counters to the local context. + */ - /* Save all group 0 counters */ - for (i = 0U; i < read_amcgcr_cg0nc(); i++) { + isb(); /* Ensure counters have been stopped */ + + for (i = 0U; i < amcgcr_cg0nc; i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); } #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Save group 1 counters */ - for (i = 0U; i < read_amcgcr_cg1nc(); i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { - ctx->group1_cnts[i] = amu_group1_cnt_read(i); - } - } + for (i = 0U; i < amcgcr_cg1nc; i++) { + ctx->group1_cnts[i] = amu_group1_cnt_read(i); } #endif @@ -269,41 +319,69 @@ static void *amu_context_save(const void *arg) static void *amu_context_restore(const void *arg) { - struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - unsigned int i; + uint32_t i; + + unsigned int core_pos; + struct amu_ctx *ctx; - if (!amu_supported()) { - return (void *)-1; + uint32_t id_pfr0_amu; /* AMU version */ + + uint32_t amcfgr_ncg; /* Number of counter groups */ + uint32_t amcgcr_cg0nc; /* Number of group 0 counters */ + +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint32_t amcgcr_cg1nc; /* Number of group 1 counters */ +#endif + + id_pfr0_amu = read_id_pfr0_amu(); + if (id_pfr0_amu == ID_PFR0_AMU_NOT_SUPPORTED) { + return (void *)0; } - /* Counters were disabled in `amu_context_save()` */ - assert(read_amcntenset0_px() == 0U); + core_pos = plat_my_core_pos(); + ctx = &amu_ctxs_[core_pos]; + + amcfgr_ncg = read_amcfgr_ncg(); + amcgcr_cg0nc = read_amcgcr_cg0nc(); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { + amcgcr_cg1nc = (amcfgr_ncg > 0U) ? read_amcgcr_cg1nc() : 0U; +#endif + + /* + * Sanity check that all counters were disabled when the context was + * previously saved. + */ + + assert(read_amcntenset0_px() == 0U); + + if (amcfgr_ncg > 0U) { assert(read_amcntenset1_px() == 0U); } -#endif - /* Restore all group 0 counters */ - for (i = 0U; i < read_amcgcr_cg0nc(); i++) { + /* + * Restore the counter values from the local context. + */ + + for (i = 0U; i < amcgcr_cg0nc; i++) { amu_group0_cnt_write(i, ctx->group0_cnts[i]); } - /* Restore group 0 counter configuration */ - write_amcntenset0_px((UINT32_C(1) << read_amcgcr_cg0nc()) - 1U); +#if ENABLE_AMU_AUXILIARY_COUNTERS + for (i = 0U; i < amcgcr_cg1nc; i++) { + amu_group1_cnt_write(i, ctx->group1_cnts[i]); + } +#endif + + /* + * Re-enable counters that were disabled during context save. + */ + + write_amcntenset0_px(ctx->group0_enable); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Restore group 1 counters */ - for (i = 0U; i < read_amcgcr_cg1nc(); i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1U << i)) != 0U) { - amu_group1_cnt_write(i, ctx->group1_cnts[i]); - } - } - - /* Restore group 1 counter configuration */ - write_amcntenset1_px(AMU_GROUP1_COUNTERS_MASK); + if (amcfgr_ncg > 0U) { + write_amcntenset1_px(ctx->group1_enable); } #endif diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 6bed6c3cf..58094ae40 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -8,17 +8,42 @@ #include #include +#include "../amu_private.h" #include #include #include - #include #include -#include #include -static struct amu_ctx amu_ctxs[PLATFORM_CORE_COUNT]; +struct amu_ctx { + uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint64_t group1_cnts[AMU_GROUP1_MAX_COUNTERS]; +#endif + + /* Architected event counter 1 does not have an offset register */ + uint64_t group0_voffsets[AMU_GROUP0_MAX_COUNTERS - 1U]; +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint64_t group1_voffsets[AMU_GROUP1_MAX_COUNTERS]; +#endif + + uint16_t group0_enable; +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint16_t group1_enable; +#endif +}; + +static struct amu_ctx amu_ctxs_[PLATFORM_CORE_COUNT]; + +CASSERT((sizeof(amu_ctxs_[0].group0_enable) * CHAR_BIT) <= AMU_GROUP0_MAX_COUNTERS, + amu_ctx_group0_enable_cannot_represent_all_group0_counters); + +#if ENABLE_AMU_AUXILIARY_COUNTERS +CASSERT((sizeof(amu_ctxs_[0].group1_enable) * CHAR_BIT) <= AMU_GROUP1_MAX_COUNTERS, + amu_ctx_group1_enable_cannot_represent_all_group1_counters); +#endif static inline __unused uint64_t read_id_aa64pfr0_el1_amu(void) { @@ -66,7 +91,7 @@ static inline __unused uint64_t read_amcfgr_el0_ncg(void) AMCFGR_EL0_NCG_MASK; } -static inline uint64_t read_amcgcr_el0_cg0nc(void) +static inline __unused uint64_t read_amcgcr_el0_cg0nc(void) { return (read_amcgcr_el0() >> AMCGCR_EL0_CG0NC_SHIFT) & AMCGCR_EL0_CG0NC_MASK; @@ -136,37 +161,50 @@ static inline __unused void write_amcntenclr1_el0_px(uint64_t px) write_amcntenclr1_el0(value); } -static bool amu_supported(void) +static __unused bool amu_supported(void) { return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1; } -static bool amu_v1p1_supported(void) +static __unused bool amu_v1p1_supported(void) { return read_id_aa64pfr0_el1_amu() >= ID_AA64PFR0_AMU_V1P1; } #if ENABLE_AMU_AUXILIARY_COUNTERS -static bool amu_group1_supported(void) +static __unused bool amu_group1_supported(void) { return read_amcfgr_el0_ncg() > 0U; } #endif /* - * Enable counters. This function is meant to be invoked - * by the context management library before exiting from EL3. + * Enable counters. This function is meant to be invoked by the context + * management library before exiting from EL3. */ void amu_enable(bool el2_unused, cpu_context_t *ctx) { - if (!amu_supported()) { + uint64_t id_aa64pfr0_el1_amu; /* AMU version */ + + uint64_t amcfgr_el0_ncg; /* Number of counter groups */ + uint64_t amcgcr_el0_cg0nc; /* Number of group 0 counters */ + + uint64_t amcntenset0_el0_px = 0x0; /* Group 0 enable mask */ + uint64_t amcntenset1_el0_px = 0x0; /* Group 1 enable mask */ + + id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu(); + if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + /* + * If the AMU is unsupported, nothing needs to be done. + */ + return; } if (el2_unused) { /* - * CPTR_EL2.TAM: Set to zero so any accesses to - * the Activity Monitor registers do not trap to EL2. + * CPTR_EL2.TAM: Set to zero so any accesses to the Activity + * Monitor registers do not trap to EL2. */ write_cptr_el2_tam(0U); } @@ -178,18 +216,29 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) */ write_cptr_el3_tam(ctx, 0U); - /* Enable group 0 counters */ - write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); + /* + * Retrieve the number of architected counters. All of these counters + * are enabled by default. + */ + + amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc(); + amcntenset0_el0_px = (UINT64_C(1) << (amcgcr_el0_cg0nc)) - 1U; -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Enable group 1 counters */ - write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); + assert(amcgcr_el0_cg0nc <= AMU_AMCGCR_CG0NC_MAX); + + /* + * Enable the requested counters. + */ + + write_amcntenset0_el0_px(amcntenset0_el0_px); + + amcfgr_el0_ncg = read_amcfgr_el0_ncg(); + if (amcfgr_el0_ncg > 0U) { + write_amcntenset1_el0_px(amcntenset1_el0_px); } -#endif /* Initialize FEAT_AMUv1p1 features if present. */ - if (!amu_v1p1_supported()) { + if (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) { return; } @@ -232,6 +281,31 @@ static void amu_group0_cnt_write(unsigned int idx, uint64_t val) isb(); } +/* + * Unlike with auxiliary counters, we cannot detect at runtime whether an + * architected counter supports a virtual offset. These are instead fixed + * according to FEAT_AMUv1p1, but this switch will need to be updated if later + * revisions of FEAT_AMU add additional architected counters. + */ +static bool amu_group0_voffset_supported(uint64_t idx) +{ + switch (idx) { + case 0U: + case 2U: + case 3U: + return true; + + case 1U: + return false; + + default: + ERROR("AMU: can't set up virtual offset for unknown " + "architected counter %llu!\n", idx); + + panic(); + } +} + /* * Read the group 0 offset register for a given index. Index must be 0, 2, * or 3, the register for 1 does not exist. @@ -319,135 +393,192 @@ static void amu_group1_voffset_write(unsigned int idx, uint64_t val) static void *amu_context_save(const void *arg) { - struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - unsigned int i; + uint64_t i, j; - if (!amu_supported()) { - return (void *)-1; - } + unsigned int core_pos; + struct amu_ctx *ctx; - /* Assert that group 0/1 counter configuration is what we expect */ - assert(read_amcntenset0_el0_px() == - ((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U)); + uint64_t id_aa64pfr0_el1_amu; /* AMU version */ + uint64_t hcr_el2_amvoffen; /* AMU virtual offsets enabled */ + uint64_t amcgcr_el0_cg0nc; /* Number of group 0 counters */ #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - assert(read_amcntenset1_el0_px() == AMU_GROUP1_COUNTERS_MASK); + uint64_t amcg1idr_el0_voff; /* Auxiliary counters with virtual offsets */ + uint64_t amcfgr_el0_ncg; /* Number of counter groups */ + uint64_t amcgcr_el0_cg1nc; /* Number of group 1 counters */ +#endif + + id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu(); + if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + return (void *)0; } + + core_pos = plat_my_core_pos(); + ctx = &amu_ctxs_[core_pos]; + + amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc(); + hcr_el2_amvoffen = (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) ? + read_hcr_el2_amvoffen() : 0U; + +#if ENABLE_AMU_AUXILIARY_COUNTERS + amcfgr_el0_ncg = read_amcfgr_el0_ncg(); + amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U; + amcg1idr_el0_voff = (hcr_el2_amvoffen != 0U) ? read_amcg1idr_el0_voff() : 0U; #endif /* - * Disable group 0/1 counters to avoid other observers like SCP sampling - * counter values from the future via the memory mapped view. + * Disable all AMU counters. */ - write_amcntenclr0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); + + ctx->group0_enable = read_amcntenset0_el0_px(); + write_amcntenclr0_el0_px(ctx->group0_enable); #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - write_amcntenclr1_el0_px(AMU_GROUP1_COUNTERS_MASK); + if (amcfgr_el0_ncg > 0U) { + ctx->group1_enable = read_amcntenset1_el0_px(); + write_amcntenclr1_el0_px(ctx->group1_enable); } #endif - isb(); + /* + * Save the counters to the local context. + */ - /* Save all group 0 counters */ - for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) { + isb(); /* Ensure counters have been stopped */ + + for (i = 0U; i < amcgcr_el0_cg0nc; i++) { ctx->group0_cnts[i] = amu_group0_cnt_read(i); } - /* Save group 0 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - /* Not using a loop because count is fixed and index 1 DNE. */ - ctx->group0_voffsets[0U] = amu_group0_voffset_read(0U); - ctx->group0_voffsets[1U] = amu_group0_voffset_read(2U); - ctx->group0_voffsets[2U] = amu_group0_voffset_read(3U); +#if ENABLE_AMU_AUXILIARY_COUNTERS + for (i = 0U; i < amcgcr_el0_cg1nc; i++) { + ctx->group1_cnts[i] = amu_group1_cnt_read(i); } +#endif -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Save group 1 counters */ - for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { - ctx->group1_cnts[i] = amu_group1_cnt_read(i); + /* + * Save virtual offsets for counters that offer them. + */ + + if (hcr_el2_amvoffen != 0U) { + for (i = 0U, j = 0U; i < amcgcr_el0_cg0nc; i++) { + if (!amu_group0_voffset_supported(i)) { + continue; /* No virtual offset */ } - } - /* Save group 1 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - uint64_t amcg1idr = read_amcg1idr_el0_voff() & - AMU_GROUP1_COUNTERS_MASK; + ctx->group0_voffsets[j++] = amu_group0_voffset_read(i); + } - for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { - if (((amcg1idr >> i) & 1ULL) != 0ULL) { - ctx->group1_voffsets[i] = - amu_group1_voffset_read(i); - } +#if ENABLE_AMU_AUXILIARY_COUNTERS + for (i = 0U, j = 0U; i < amcgcr_el0_cg1nc; i++) { + if ((amcg1idr_el0_voff >> i) & 1U) { + continue; /* No virtual offset */ } + + ctx->group1_voffsets[j++] = amu_group1_voffset_read(i); } - } #endif + } return (void *)0; } static void *amu_context_restore(const void *arg) { - struct amu_ctx *ctx = &amu_ctxs[plat_my_core_pos()]; - unsigned int i; + uint64_t i, j; - if (!amu_supported()) { - return (void *)-1; + unsigned int core_pos; + struct amu_ctx *ctx; + + uint64_t id_aa64pfr0_el1_amu; /* AMU version */ + + uint64_t hcr_el2_amvoffen; /* AMU virtual offsets enabled */ + + uint64_t amcfgr_el0_ncg; /* Number of counter groups */ + uint64_t amcgcr_el0_cg0nc; /* Number of group 0 counters */ + +#if ENABLE_AMU_AUXILIARY_COUNTERS + uint64_t amcgcr_el0_cg1nc; /* Number of group 1 counters */ + uint64_t amcg1idr_el0_voff; /* Auxiliary counters with virtual offsets */ +#endif + + id_aa64pfr0_el1_amu = read_id_aa64pfr0_el1_amu(); + if (id_aa64pfr0_el1_amu == ID_AA64PFR0_AMU_NOT_SUPPORTED) { + return (void *)0; } - /* Counters were disabled in `amu_context_save()` */ - assert(read_amcntenset0_el0_px() == 0U); + core_pos = plat_my_core_pos(); + ctx = &amu_ctxs_[core_pos]; + + amcfgr_el0_ncg = read_amcfgr_el0_ncg(); + amcgcr_el0_cg0nc = read_amcgcr_el0_cg0nc(); + + hcr_el2_amvoffen = (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) ? + read_hcr_el2_amvoffen() : 0U; #if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { + amcgcr_el0_cg1nc = (amcfgr_el0_ncg > 0U) ? read_amcgcr_el0_cg1nc() : 0U; + amcg1idr_el0_voff = (hcr_el2_amvoffen != 0U) ? read_amcg1idr_el0_voff() : 0U; +#endif + + /* + * Sanity check that all counters were disabled when the context was + * previously saved. + */ + + assert(read_amcntenset0_el0_px() == 0U); + + if (amcfgr_el0_ncg > 0U) { assert(read_amcntenset1_el0_px() == 0U); } -#endif - /* Restore all group 0 counters */ - for (i = 0U; i < read_amcgcr_el0_cg0nc(); i++) { + /* + * Restore the counter values from the local context. + */ + + for (i = 0U; i < amcgcr_el0_cg0nc; i++) { amu_group0_cnt_write(i, ctx->group0_cnts[i]); } - /* Restore group 0 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - /* Not using a loop because count is fixed and index 1 DNE. */ - amu_group0_voffset_write(0U, ctx->group0_voffsets[0U]); - amu_group0_voffset_write(2U, ctx->group0_voffsets[1U]); - amu_group0_voffset_write(3U, ctx->group0_voffsets[2U]); +#if ENABLE_AMU_AUXILIARY_COUNTERS + for (i = 0U; i < amcgcr_el0_cg1nc; i++) { + amu_group1_cnt_write(i, ctx->group1_cnts[i]); } +#endif - /* Restore group 0 counter configuration */ - write_amcntenset0_el0_px((UINT64_C(1) << read_amcgcr_el0_cg0nc()) - 1U); + /* + * Restore virtual offsets for counters that offer them. + */ -#if ENABLE_AMU_AUXILIARY_COUNTERS - if (amu_group1_supported()) { - /* Restore group 1 counters */ - for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { - if ((AMU_GROUP1_COUNTERS_MASK & (1UL << i)) != 0U) { - amu_group1_cnt_write(i, ctx->group1_cnts[i]); + if (hcr_el2_amvoffen != 0U) { + for (i = 0U, j = 0U; i < amcgcr_el0_cg0nc; i++) { + if (!amu_group0_voffset_supported(i)) { + continue; /* No virtual offset */ } - } - /* Restore group 1 virtual offsets if supported and enabled. */ - if (amu_v1p1_supported() && (read_hcr_el2_amvoffen() != 0U)) { - uint64_t amcg1idr = read_amcg1idr_el0_voff() & - AMU_GROUP1_COUNTERS_MASK; + amu_group0_voffset_write(i, ctx->group0_voffsets[j++]); + } - for (i = 0U; i < read_amcgcr_el0_cg1nc(); i++) { - if (((amcg1idr >> i) & 1ULL) != 0ULL) { - amu_group1_voffset_write(i, - ctx->group1_voffsets[i]); - } +#if ENABLE_AMU_AUXILIARY_COUNTERS + for (i = 0U, j = 0U; i < amcgcr_el0_cg1nc; i++) { + if ((amcg1idr_el0_voff >> i) & 1U) { + continue; /* No virtual offset */ } + + amu_group1_voffset_write(i, ctx->group1_voffsets[j++]); } +#endif + } + + /* + * Re-enable counters that were disabled during context save. + */ + + write_amcntenset0_el0_px(ctx->group0_enable); - /* Restore group 1 counter configuration */ - write_amcntenset1_el0_px(AMU_GROUP1_COUNTERS_MASK); +#if ENABLE_AMU_AUXILIARY_COUNTERS + if (amcfgr_el0_ncg > 0) { + write_amcntenset1_el0_px(ctx->group1_enable); } #endif diff --git a/lib/extensions/amu/amu_private.h b/lib/extensions/amu/amu_private.h new file mode 100644 index 000000000..eb7ff0e89 --- /dev/null +++ b/lib/extensions/amu/amu_private.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AMU_PRIVATE_H +#define AMU_PRIVATE_H + +#include + +#include +#include +#include + +#include + +#define AMU_GROUP0_MAX_COUNTERS U(16) +#define AMU_GROUP1_MAX_COUNTERS U(16) + +#define AMU_AMCGCR_CG0NC_MAX U(16) + +uint64_t amu_group0_cnt_read_internal(unsigned int idx); +void amu_group0_cnt_write_internal(unsigned int idx, uint64_t val); + +uint64_t amu_group1_cnt_read_internal(unsigned int idx); +void amu_group1_cnt_write_internal(unsigned int idx, uint64_t val); +void amu_group1_set_evtype_internal(unsigned int idx, unsigned int val); + +#if __aarch64__ +uint64_t amu_group0_voffset_read_internal(unsigned int idx); +void amu_group0_voffset_write_internal(unsigned int idx, uint64_t val); + +uint64_t amu_group1_voffset_read_internal(unsigned int idx); +void amu_group1_voffset_write_internal(unsigned int idx, uint64_t val); +#endif + +#endif /* AMU_PRIVATE_H */ -- cgit v1.2.3 From 9cf75647235ad243acc7a585696ccb7b5ff54b36 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 17 Aug 2021 16:24:57 +0100 Subject: docs(amu): add AMU documentation This change adds some documentation on the AMU and its purpose. This is expanded on in later patches. Change-Id: If2834676790938d8da5ea2ceba37b674f6cc0f01 Signed-off-by: Chris Kay --- docs/components/activity-monitors.rst | 15 +++++++++++++++ docs/components/index.rst | 1 + docs/global_substitutions.txt | 2 ++ docs/glossary.rst | 4 ++++ 4 files changed, 22 insertions(+) create mode 100644 docs/components/activity-monitors.rst diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst new file mode 100644 index 000000000..57d81f88b --- /dev/null +++ b/docs/components/activity-monitors.rst @@ -0,0 +1,15 @@ +Activity Monitors +================= + +FEAT_AMUv1 of the Armv8-A architecture introduces the Activity Monitors +extension. This extension describes the architecture for the Activity Monitor +Unit (|AMU|), an optional non-invasive component for monitoring core events +through a set of 64-bit counters. + +When the ``ENABLE_AMU=1`` build option is provided, Trusted Firmware-A sets up +the |AMU| prior to its exit from EL3, and will save and restore architected +|AMU| counters as necessary upon suspend and resume. + +-------------- + +*Copyright (c) 2021, Arm Limited. All rights reserved.* diff --git a/docs/components/index.rst b/docs/components/index.rst index f349d8dcc..e46751651 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -7,6 +7,7 @@ Components :numbered: spd/index + activity-monitors arm-sip-service debugfs-design exception-handling diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index 24ac8300e..a70f15e3d 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -1,5 +1,7 @@ .. |AArch32| replace:: :term:`AArch32` .. |AArch64| replace:: :term:`AArch64` +.. |AMU| replace:: :term:`AMU` +.. |AMUs| replace:: :term:`AMUs ` .. |API| replace:: :term:`API` .. |BTI| replace:: :term:`BTI` .. |CoT| replace:: :term:`CoT` diff --git a/docs/glossary.rst b/docs/glossary.rst index f4912f518..a062319ce 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -15,6 +15,10 @@ You can find additional definitions in the `Arm Glossary`_. AArch64 64-bit execution state of the ARMv8 ISA + AMU + Activity Monitor Unit, a hardware monitoring unit introduced by FEAT_AMUv1 + that exposes CPU core runtime metrics as a set of counter registers. + API Application Programming Interface -- cgit v1.2.3 From 742ca2307f4e9f82cb2c21518819425e5bcc0f90 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 19 Aug 2021 11:21:52 +0100 Subject: feat(amu): enable per-core AMU auxiliary counters This change makes AMU auxiliary counters configurable on a per-core basis, controlled by `ENABLE_AMU_AUXILIARY_COUNTERS`. Auxiliary counters can be described via the `HW_CONFIG` device tree if the `ENABLE_AMU_FCONF` build option is enabled, or the platform must otherwise implement the `plat_amu_topology` function. A new phandle property for `cpu` nodes (`amu`) has been introduced to the `HW_CONFIG` specification to allow CPUs to describe the view of their own AMU: ``` cpu0: cpu@0 { ... amu = <&cpu0_amu>; }; ``` Multiple cores may share an `amu` handle if they implement the same set of auxiliary counters. AMU counters are described for one or more AMUs through the use of a new `amus` node: ``` amus { cpu0_amu: amu-0 { #address-cells = <1>; #size-cells = <0>; counter@0 { reg = <0>; enable-at-el3; }; counter@n { reg = ; ... }; }; }; ``` This structure describes the **auxiliary** (group 1) AMU counters. Architected counters have architecturally-defined behaviour, and as such do not require DTB entries. These `counter` nodes support two properties: - The `reg` property represents the counter register index. - The presence of the `enable-at-el3` property determines whether the firmware should enable the counter prior to exiting EL3. Change-Id: Ie43aee010518c5725a3b338a4899b0857caf4c28 Signed-off-by: Chris Kay --- Makefile | 2 + docs/components/activity-monitors.rst | 17 +++ docs/components/fconf/amu-bindings.rst | 142 +++++++++++++++++++++++ docs/components/fconf/index.rst | 1 + docs/getting_started/build-options.rst | 4 + include/lib/extensions/amu.h | 28 +++++ include/lib/fconf/fconf_amu_getter.h | 20 ++++ lib/extensions/amu/aarch32/amu.c | 29 +++++ lib/extensions/amu/aarch64/amu.c | 34 ++++++ lib/extensions/amu/amu.mk | 16 +++ lib/extensions/amu/amu_fconf.c | 200 +++++++++++++++++++++++++++++++++ lib/fconf/fconf.mk | 3 + lib/fconf/fconf_amu_getter.c | 142 +++++++++++++++++++++++ make_helpers/defaults.mk | 1 + 14 files changed, 639 insertions(+) create mode 100644 docs/components/fconf/amu-bindings.rst create mode 100644 include/lib/fconf/fconf_amu_getter.h create mode 100644 lib/extensions/amu/amu_fconf.c create mode 100644 lib/fconf/fconf_amu_getter.c diff --git a/Makefile b/Makefile index 3aa0f9c9a..21de8625f 100644 --- a/Makefile +++ b/Makefile @@ -956,6 +956,7 @@ $(eval $(call assert_booleans,\ EL3_EXCEPTION_HANDLING \ ENABLE_AMU \ ENABLE_AMU_AUXILIARY_COUNTERS \ + ENABLE_AMU_FCONF \ AMU_RESTRICT_COUNTERS \ ENABLE_ASSERTIONS \ ENABLE_MPAM_FOR_LOWER_ELS \ @@ -1058,6 +1059,7 @@ $(eval $(call add_defines,\ DISABLE_MTPMU \ ENABLE_AMU \ ENABLE_AMU_AUXILIARY_COUNTERS \ + ENABLE_AMU_FCONF \ AMU_RESTRICT_COUNTERS \ ENABLE_ASSERTIONS \ ENABLE_BTI \ diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst index 57d81f88b..ee280e287 100644 --- a/docs/components/activity-monitors.rst +++ b/docs/components/activity-monitors.rst @@ -10,6 +10,23 @@ When the ``ENABLE_AMU=1`` build option is provided, Trusted Firmware-A sets up the |AMU| prior to its exit from EL3, and will save and restore architected |AMU| counters as necessary upon suspend and resume. +Auxiliary counters +------------------ + +FEAT_AMUv1 describes a set of implementation-defined auxiliary counters (also +known as group 1 counters), controlled by the ``ENABLE_AMU_AUXILIARY_COUNTERS`` +build option. + +As a security precaution, Trusted Firmware-A does not enable these by default. +Instead, platforms may configure their auxiliary counters through one of two +possible mechanisms: + +- |FCONF|, controlled by the ``ENABLE_AMU_FCONF`` build option. +- A platform implementation of the ``plat_amu_topology`` function (the default). + +See :ref:`Activity Monitor Unit (AMU) Bindings` for documentation on the |FCONF| +device tree bindings. + -------------- *Copyright (c) 2021, Arm Limited. All rights reserved.* diff --git a/docs/components/fconf/amu-bindings.rst b/docs/components/fconf/amu-bindings.rst new file mode 100644 index 000000000..047f75ef8 --- /dev/null +++ b/docs/components/fconf/amu-bindings.rst @@ -0,0 +1,142 @@ +Activity Monitor Unit (AMU) Bindings +==================================== + +To support platform-defined Activity Monitor Unit (|AMU|) auxiliary counters +through FCONF, the ``HW_CONFIG`` device tree accepts several |AMU|-specific +nodes and properties. + +Bindings +^^^^^^^^ + +.. contents:: + :local: + +``/cpus/cpus/cpu*`` node properties +""""""""""""""""""""""""""""""""""" + +The ``cpu`` node has been augmented to support a handle to an associated |AMU| +view, which should describe the counters offered by the core. + ++---------------+-------+---------------+-------------------------------------+ +| Property name | Usage | Value type | Description | ++===============+=======+===============+=====================================+ +| ``amu`` | O | ```` | If present, indicates that an |AMU| | +| | | | is available and its counters are | +| | | | described by the node provided. | ++---------------+-------+---------------+-------------------------------------+ + +``/cpus/amus`` node properties +"""""""""""""""""""""""""""""" + +The ``amus`` node describes the |AMUs| implemented by the cores in the system. +This node does not have any properties. + +``/cpus/amus/amu*`` node properties +""""""""""""""""""""""""""""""""""" + +An ``amu`` node describes the layout and meaning of the auxiliary counter +registers of one or more |AMUs|, and may be shared by multiple cores. + ++--------------------+-------+------------+------------------------------------+ +| Property name | Usage | Value type | Description | ++====================+=======+============+====================================+ +| ``#address-cells`` | R | ```` | Value shall be 1. Specifies that | +| | | | the ``reg`` property array of | +| | | | children of this node uses a | +| | | | single cell. | ++--------------------+-------+------------+------------------------------------+ +| ``#size-cells`` | R | ```` | Value shall be 0. Specifies that | +| | | | no size is required in the ``reg`` | +| | | | property in children of this node. | ++--------------------+-------+------------+------------------------------------+ + +``/cpus/amus/amu*/counter*`` node properties +"""""""""""""""""""""""""""""""""""""""""""" + +A ``counter`` node describes an auxiliary counter belonging to the parent |AMU| +view. + ++-------------------+-------+-------------+------------------------------------+ +| Property name | Usage | Value type | Description | ++===================+=======+=============+====================================+ +| ``reg`` | R | array | Represents the counter register | +| | | | index, and must be a single cell. | ++-------------------+-------+-------------+------------------------------------+ +| ``enable-at-el3`` | O | ```` | The presence of this property | +| | | | indicates that this counter should | +| | | | be enabled prior to EL3 exit. | ++-------------------+-------+-------------+------------------------------------+ + +Example +^^^^^^^ + +An example system offering four cores made up of two clusters, where the cores +of each cluster share different |AMUs|, may use something like the following: + +.. code-block:: + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + amus { + amu0: amu-0 { + #address-cells = <1>; + #size-cells = <0>; + + counterX: counter@0 { + reg = <0>; + + enable-at-el3; + }; + + counterY: counter@1 { + reg = <1>; + + enable-at-el3; + }; + }; + + amu1: amu-1 { + #address-cells = <1>; + #size-cells = <0>; + + counterZ: counter@0 { + reg = <0>; + + enable-at-el3; + }; + }; + }; + + cpu0@00000 { + ... + + amu = <&amu0>; + }; + + cpu1@00100 { + ... + + amu = <&amu0>; + }; + + cpu2@10000 { + ... + + amu = <&amu1>; + }; + + cpu3@10100 { + ... + + amu = <&amu1>; + }; + } + +In this situation, ``cpu0`` and ``cpu1`` (the two cores in the first cluster), +share the view of their AMUs defined by ``amu0``. Likewise, ``cpu2`` and +``cpu3`` (the two cores in the second cluster), share the view of their |AMUs| +defined by ``amu1``. This will cause ``counterX`` and ``counterY`` to be enabled +for both ``cpu0`` and ``cpu1``, and ``counterZ`` to be enabled for both ``cpu2`` +and ``cpu3``. diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst index 902063356..00a4e297b 100644 --- a/docs/components/fconf/index.rst +++ b/docs/components/fconf/index.rst @@ -145,3 +145,4 @@ Properties binding information :maxdepth: 1 fconf_properties + amu-bindings diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index f9999e108..8a0167b6d 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -224,6 +224,10 @@ Common build options (also known as group 1 counters). These are implementation-defined counters, and as such require additional platform configuration. Default is 0. +- ``ENABLE_AMU_FCONF``: Enables configuration of the AMU through FCONF, which + allows platforms with auxiliary counters to describe them via the + ``HW_CONFIG`` device tree blob. Default is 0. + - ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()`` are compiled out. For debug builds, this option defaults to 1, and calls to ``assert()`` are left in place. For release builds, this option defaults to 0 diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h index 692d1adaf..6452f7e48 100644 --- a/include/lib/extensions/amu.h +++ b/include/lib/extensions/amu.h @@ -8,12 +8,40 @@ #define AMU_H #include +#include + #include +#include + #if __aarch64__ void amu_enable(bool el2_unused, cpu_context_t *ctx); #else void amu_enable(bool el2_unused); #endif +#if ENABLE_AMU_AUXILIARY_COUNTERS +/* + * AMU data for a single core. + */ +struct amu_core { + uint16_t enable; /* Mask of auxiliary counters to enable */ +}; + +/* + * Topological platform data specific to the AMU. + */ +struct amu_topology { + struct amu_core cores[PLATFORM_CORE_COUNT]; /* Per-core data */ +}; + +#if !ENABLE_AMU_FCONF +/* + * Retrieve the platform's AMU topology. A `NULL` return value is treated as a + * non-fatal error, in which case no auxiliary counters will be enabled. + */ +const struct amu_topology *plat_amu_topology(void); +#endif /* ENABLE_AMU_FCONF */ +#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */ + #endif /* AMU_H */ diff --git a/include/lib/fconf/fconf_amu_getter.h b/include/lib/fconf/fconf_amu_getter.h new file mode 100644 index 000000000..2faee73b4 --- /dev/null +++ b/include/lib/fconf/fconf_amu_getter.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_AMU_GETTER_H +#define FCONF_AMU_GETTER_H + +#include + +#define amu__config_getter(id) fconf_amu_config.id + +struct fconf_amu_config { + const struct amu_topology *topology; +}; + +extern struct fconf_amu_config fconf_amu_config; + +#endif /* FCONF_AMU_GETTER_H */ diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c index e92b9f130..57b115825 100644 --- a/lib/extensions/amu/aarch32/amu.c +++ b/lib/extensions/amu/aarch32/amu.c @@ -11,6 +11,7 @@ #include "../amu_private.h" #include #include +#include #include #include @@ -181,6 +182,30 @@ void amu_enable(bool el2_unused) assert(amcgcr_cg0nc <= AMU_AMCGCR_CG0NC_MAX); + /* + * The platform may opt to enable specific auxiliary counters. This can + * be done via the common FCONF getter, or via the platform-implemented + * function. + */ + +#if ENABLE_AMU_AUXILIARY_COUNTERS + const struct amu_topology *topology; + +#if ENABLE_AMU_FCONF + topology = FCONF_GET_PROPERTY(amu, config, topology); +#else + topology = plat_amu_topology(); +#endif /* ENABLE_AMU_FCONF */ + + if (topology != NULL) { + unsigned int core_pos = plat_my_core_pos(); + + amcntenset1_el0_px = topology->cores[core_pos].enable; + } else { + ERROR("AMU: failed to generate AMU topology\n"); + } +#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */ + /* * Enable the requested counters. */ @@ -190,6 +215,10 @@ void amu_enable(bool el2_unused) amcfgr_ncg = read_amcfgr_ncg(); if (amcfgr_ncg > 0U) { write_amcntenset1_px(amcntenset1_px); + +#if !ENABLE_AMU_AUXILIARY_COUNTERS + VERBOSE("AMU: auxiliary counters detected but support is disabled\n"); +#endif } /* Initialize FEAT_AMUv1p1 features if present. */ diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 58094ae40..f7125204a 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -12,11 +12,17 @@ #include #include #include +#include #include #include #include +#if ENABLE_AMU_FCONF +# include +# include +#endif + struct amu_ctx { uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; #if ENABLE_AMU_AUXILIARY_COUNTERS @@ -226,6 +232,30 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) assert(amcgcr_el0_cg0nc <= AMU_AMCGCR_CG0NC_MAX); + /* + * The platform may opt to enable specific auxiliary counters. This can + * be done via the common FCONF getter, or via the platform-implemented + * function. + */ + +#if ENABLE_AMU_AUXILIARY_COUNTERS + const struct amu_topology *topology; + +#if ENABLE_AMU_FCONF + topology = FCONF_GET_PROPERTY(amu, config, topology); +#else + topology = plat_amu_topology(); +#endif /* ENABLE_AMU_FCONF */ + + if (topology != NULL) { + unsigned int core_pos = plat_my_core_pos(); + + amcntenset1_el0_px = topology->cores[core_pos].enable; + } else { + ERROR("AMU: failed to generate AMU topology\n"); + } +#endif /* ENABLE_AMU_AUXILIARY_COUNTERS */ + /* * Enable the requested counters. */ @@ -235,6 +265,10 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) amcfgr_el0_ncg = read_amcfgr_el0_ncg(); if (amcfgr_el0_ncg > 0U) { write_amcntenset1_el0_px(amcntenset1_el0_px); + +#if !ENABLE_AMU_AUXILIARY_COUNTERS + VERBOSE("AMU: auxiliary counters detected but support is disabled\n"); +#endif } /* Initialize FEAT_AMUv1p1 features if present. */ diff --git a/lib/extensions/amu/amu.mk b/lib/extensions/amu/amu.mk index b4e04dd47..0d203cb1f 100644 --- a/lib/extensions/amu/amu.mk +++ b/lib/extensions/amu/amu.mk @@ -4,5 +4,21 @@ # SPDX-License-Identifier: BSD-3-Clause # +include lib/fconf/fconf.mk + AMU_SOURCES := lib/extensions/amu/${ARCH}/amu.c \ lib/extensions/amu/${ARCH}/amu_helpers.S + +ifneq (${ENABLE_AMU_AUXILIARY_COUNTERS},0) + ifeq (${ENABLE_AMU},0) + $(error AMU auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) requires AMU support (`ENABLE_AMU`)) + endif +endif + +ifneq (${ENABLE_AMU_FCONF},0) + ifeq (${ENABLE_AMU_AUXILIARY_COUNTERS},0) + $(error AMU FCONF support (`ENABLE_AMU_FCONF`) is not necessary when auxiliary counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`) is disabled) + endif + + AMU_SOURCES += ${FCONF_AMU_SOURCES} +endif diff --git a/lib/extensions/amu/amu_fconf.c b/lib/extensions/amu/amu_fconf.c new file mode 100644 index 000000000..c7fb80362 --- /dev/null +++ b/lib/extensions/amu/amu_fconf.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "amu_private.h" +#include +#include +#include +#include +#include + +#include + +static bool amu_topology_populated_ ; /* Whether the topology is valid */ +static struct amu_fconf_topology amu_topology_; /* Populated topology cache */ + +const struct amu_fconf_topology *amu_topology(void) +{ + if (!amu_topology_populated_) { + return NULL; + } + + return &amu_topology_; +} + +/* + * Populate the core-specific AMU structure with information retrieved from a + * device tree. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int amu_fconf_populate_cpu_amu(const void *fdt, int parent, + struct amu_fconf_core *amu) +{ + int ret = 0; + int node = 0; + + fdt_for_each_subnode(node, fdt, parent) { + const char *name; + const char *value; + int len; + + uintptr_t idx = 0U; + + name = fdt_get_name(fdt, node, &len); + if (strncmp(name, "counter@", 8) != 0) { + continue; + } + + ret = fdt_get_reg_props_by_index(fdt, node, 0, &idx, NULL); + if (ret < 0) { + break; + } + + value = fdt_getprop(fdt, node, "enable-at-el3", &len); + if ((value == NULL) && (len != -FDT_ERR_NOTFOUND)) { + break; + } + + if (len != -FDT_ERR_NOTFOUND) { + amu->enable |= (1 << idx); + } + } + + if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { + return node; + } + + return ret; +} + +/* + * Within a `cpu` node, attempt to dereference the `amu` property, and populate + * the AMU information for the core. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int amu_fconf_populate_cpu(const void *fdt, int node, uintptr_t mpidr) +{ + int ret; + int idx; + + uint32_t amu_phandle; + struct amu_fconf_core *amu; + + ret = fdt_read_uint32(fdt, node, "amu", &amu_phandle); + if (ret < 0) { + if (ret == -FDT_ERR_NOTFOUND) { + ret = 0; + } + + return ret; + } + + node = fdt_node_offset_by_phandle(fdt, amu_phandle); + if (node < 0) { + return node; + } + + idx = plat_core_pos_by_mpidr(mpidr); + amu = &amu_topology_.cores[idx]; + + return amu_fconf_populate_cpu_amu(fdt, node, amu); +} + +/* + * For every CPU node (`/cpus/cpu@n`) in an FDT, executes a callback passing a + * pointer to the FDT and the offset of the CPU node. If the return value of the + * callback is negative, it is treated as an error and the loop is aborted. In + * this situation, the value of the callback is returned from the function. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int amu_fconf_foreach_cpu(const void *fdt, + int (*callback)(const void *, int, uintptr_t)) +{ + int ret = 0; + int parent, node = 0; + + parent = fdt_path_offset(fdt, "/cpus"); + if (parent < 0) { + if (parent == -FDT_ERR_NOTFOUND) { + parent = 0; + } + + return parent; + } + + fdt_for_each_subnode(node, fdt, parent) { + const char *name; + int len; + + uintptr_t mpidr = 0U; + + name = fdt_get_name(fdt, node, &len); + if (strncmp(name, "cpu@", 4) != 0) { + continue; + } + + ret = fdt_get_reg_props_by_index(fdt, node, 0, &mpidr, NULL); + if (ret < 0) { + break; + } + + ret = callback(fdt, node, mpidr); + if (ret < 0) { + break; + } + } + + if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { + return node; + } + + return ret; +} + +/* + * Populates the global `amu_topology` structure based on what's described by + * the hardware configuration device tree blob. + * + * The device tree is expected to provide an `amu` property for each `cpu` node, + * like so: + * + * cpu@0 { + * amu = <&cpu0_amu>; + * }; + * + * amus { + * cpu0_amu: amu-0 { + * counters { + * #address-cells = <2>; + * #size-cells = <0>; + * + * counter@x,y { + * reg = ; // Group x, counter y + * }; + * }; + * }; + * }; + */ +static int amu_fconf_populate(uintptr_t config) +{ + int ret = amu_fconf_foreach_cpu( + (const void *)config, amu_fconf_populate_cpu); + if (ret < 0) { + ERROR("AMU-FCONF: Failed to configure AMU: %d\n", ret); + } else { + amu_topology_populated_ = true; + } + + return ret; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, amu, amu_fconf_populate); diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index bc6f60840..18bcb3590 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -11,3 +11,6 @@ FCONF_SOURCES += ${FDT_WRAPPERS_SOURCES} FCONF_DYN_SOURCES := lib/fconf/fconf_dyn_cfg_getter.c FCONF_DYN_SOURCES += ${FDT_WRAPPERS_SOURCES} + +FCONF_AMU_SOURCES := lib/fconf/fconf_amu_getter.c +FCONF_AMU_SOURCES += ${FDT_WRAPPERS_SOURCES} diff --git a/lib/fconf/fconf_amu_getter.c b/lib/fconf/fconf_amu_getter.c new file mode 100644 index 000000000..eff309cf9 --- /dev/null +++ b/lib/fconf/fconf_amu_getter.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +struct fconf_amu_config fconf_amu_config; +static struct amu_topology fconf_amu_topology_; + +/* + * Populate the core-specific AMU structure with information retrieved from a + * device tree. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int fconf_populate_amu_cpu_amu(const void *fdt, int parent, + struct amu_core *amu) +{ + int ret = 0; + int node = 0; + + fdt_for_each_subnode(node, fdt, parent) { + const char *name; + const char *value; + int len; + + uintptr_t idx = 0U; + + name = fdt_get_name(fdt, node, &len); + if (strncmp(name, "counter@", 8) != 0) { + continue; + } + + ret = fdt_get_reg_props_by_index(fdt, node, 0, &idx, NULL); + if (ret < 0) { + break; + } + + value = fdt_getprop(fdt, node, "enable-at-el3", &len); + if ((value == NULL) && (len != -FDT_ERR_NOTFOUND)) { + break; + } + + if (len != -FDT_ERR_NOTFOUND) { + amu->enable |= (1 << idx); + } + } + + if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { + return node; + } + + return ret; +} + +/* + * Within a `cpu` node, attempt to dereference the `amu` property, and populate + * the AMU information for the core. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int fconf_populate_amu_cpu(const void *fdt, int node, uintptr_t mpidr) +{ + int ret; + int idx; + + uint32_t amu_phandle; + struct amu_core *amu; + + ret = fdt_read_uint32(fdt, node, "amu", &amu_phandle); + if (ret < 0) { + if (ret == -FDT_ERR_NOTFOUND) { + ret = 0; + } + + return ret; + } + + node = fdt_node_offset_by_phandle(fdt, amu_phandle); + if (node < 0) { + return node; + } + + idx = plat_core_pos_by_mpidr(mpidr); + if (idx < 0) { + return -FDT_ERR_BADVALUE; + } + + amu = &fconf_amu_topology_.cores[idx]; + + return fconf_populate_amu_cpu_amu(fdt, node, amu); +} + +/* + * Populates the global `amu_topology` structure based on what's described by + * the hardware configuration device tree blob. + * + * The device tree is expected to provide an `amu` property for each `cpu` node, + * like so: + * + * cpu@0 { + * amu = <&cpu0_amu>; + * }; + * + * amus { + * cpu0_amu: amu-0 { + * counters { + * #address-cells = <2>; + * #size-cells = <0>; + * + * counter@x,y { + * reg = ; // Group x, counter y + * }; + * }; + * }; + * }; + */ +static int fconf_populate_amu(uintptr_t config) +{ + int ret = fdtw_for_each_cpu( + (const void *)config, fconf_populate_amu_cpu); + if (ret == 0) { + fconf_amu_config.topology = &fconf_amu_topology_; + } else { + ERROR("FCONF: failed to parse AMU information: %d\n", ret); + } + + return ret; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, amu, fconf_populate_amu); diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 4344cf8ba..8705d9247 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -307,6 +307,7 @@ CTX_INCLUDE_MTE_REGS := 0 ENABLE_AMU := 0 ENABLE_AMU_AUXILIARY_COUNTERS := 0 +ENABLE_AMU_FCONF := 0 AMU_RESTRICT_COUNTERS := 0 # By default, enable Scalable Vector Extension if implemented only for Non-secure -- cgit v1.2.3 From 68120783d6d6f99c605e9f746ee0e91e2908feb1 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Wed, 5 May 2021 13:38:30 +0100 Subject: feat(mpmm): add support for MPMM MPMM - the Maximum Power Mitigation Mechanism - is an optional microarchitectural feature present on some Armv9-A cores, introduced with the Cortex-X2, Cortex-A710 and Cortex-A510 cores. MPMM allows the SoC firmware to detect and limit high activity events to assist in SoC processor power domain dynamic power budgeting and limit the triggering of whole-rail (i.e. clock chopping) responses to overcurrent conditions. This feature is enabled via the `ENABLE_MPMM` build option. Configuration can be done via FCONF by enabling `ENABLE_MPMM_FCONF`, or by via the plaform-implemented `plat_mpmm_topology` function. Change-Id: I77da82808ad4744ece8263f0bf215c5a091c3167 Signed-off-by: Chris Kay --- Makefile | 4 ++ bl31/bl31.mk | 5 +++ docs/components/activity-monitors.rst | 2 + docs/components/fconf/index.rst | 1 + docs/components/fconf/mpmm-bindings.rst | 48 ++++++++++++++++++++ docs/components/index.rst | 1 + docs/components/mpmm.rst | 30 +++++++++++++ docs/getting_started/build-options.rst | 10 +++++ docs/global_substitutions.txt | 1 + docs/glossary.rst | 4 ++ include/arch/aarch64/arch.h | 12 +++++ include/arch/aarch64/arch_helpers.h | 4 ++ include/lib/fconf/fconf_mpmm_getter.h | 20 +++++++++ include/lib/mpmm/mpmm.h | 57 +++++++++++++++++++++++ lib/extensions/amu/aarch64/amu.c | 47 ++++++++++++------- lib/fconf/fconf.mk | 3 ++ lib/fconf/fconf_mpmm_getter.c | 80 +++++++++++++++++++++++++++++++++ lib/mpmm/mpmm.c | 72 +++++++++++++++++++++++++++++ lib/mpmm/mpmm.mk | 29 ++++++++++++ make_helpers/defaults.mk | 6 +++ 20 files changed, 419 insertions(+), 17 deletions(-) create mode 100644 docs/components/fconf/mpmm-bindings.rst create mode 100644 docs/components/mpmm.rst create mode 100644 include/lib/fconf/fconf_mpmm_getter.h create mode 100644 include/lib/mpmm/mpmm.h create mode 100644 lib/fconf/fconf_mpmm_getter.c create mode 100644 lib/mpmm/mpmm.c create mode 100644 lib/mpmm/mpmm.mk diff --git a/Makefile b/Makefile index 21de8625f..0caa9c08e 100644 --- a/Makefile +++ b/Makefile @@ -1015,6 +1015,8 @@ $(eval $(call assert_booleans,\ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ ENABLE_FEAT_HCX \ + ENABLE_MPMM \ + ENABLE_MPMM_FCONF \ ))) $(eval $(call assert_numerics,\ @@ -1123,6 +1125,8 @@ $(eval $(call add_defines,\ ENABLE_SYS_REG_TRACE_FOR_NS \ ENABLE_TRF_FOR_NS \ ENABLE_FEAT_HCX \ + ENABLE_MPMM \ + ENABLE_MPMM_FCONF \ ))) ifeq (${SANITIZE_UB},trap) diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 4e9e99f46..9baa0c27f 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -23,6 +23,7 @@ ifeq (${SPM_MM},1) endif include lib/extensions/amu/amu.mk +include lib/mpmm/mpmm.mk include lib/psci/psci_lib.mk BL31_SOURCES += bl31/bl31_main.c \ @@ -82,6 +83,10 @@ ifeq (${ENABLE_AMU},1) BL31_SOURCES += ${AMU_SOURCES} endif +ifeq (${ENABLE_MPMM},1) +BL31_SOURCES += ${MPMM_SOURCES} +endif + ifeq (${ENABLE_SVE_FOR_NS},1) BL31_SOURCES += lib/extensions/sve/sve.c endif diff --git a/docs/components/activity-monitors.rst b/docs/components/activity-monitors.rst index ee280e287..dd45c4353 100644 --- a/docs/components/activity-monitors.rst +++ b/docs/components/activity-monitors.rst @@ -10,6 +10,8 @@ When the ``ENABLE_AMU=1`` build option is provided, Trusted Firmware-A sets up the |AMU| prior to its exit from EL3, and will save and restore architected |AMU| counters as necessary upon suspend and resume. +.. _Activity Monitor Auxiliary Counters: + Auxiliary counters ------------------ diff --git a/docs/components/fconf/index.rst b/docs/components/fconf/index.rst index 00a4e297b..029f324dc 100644 --- a/docs/components/fconf/index.rst +++ b/docs/components/fconf/index.rst @@ -146,3 +146,4 @@ Properties binding information fconf_properties amu-bindings + mpmm-bindings diff --git a/docs/components/fconf/mpmm-bindings.rst b/docs/components/fconf/mpmm-bindings.rst new file mode 100644 index 000000000..d3cc857a8 --- /dev/null +++ b/docs/components/fconf/mpmm-bindings.rst @@ -0,0 +1,48 @@ +Maximum Power Mitigation Mechanism (MPMM) Bindings +================================================== + +|MPMM| support cannot be determined at runtime by the firmware. Instead, these +DTB bindings allow the platform to communicate per-core support for |MPMM| via +the ``HW_CONFIG`` device tree blob. + +Bindings +^^^^^^^^ + +.. contents:: + :local: + +``/cpus/cpus/cpu*`` node properties +""""""""""""""""""""""""""""""""""" + +The ``cpu`` node has been augmented to allow the platform to indicate support +for |MPMM| on a given core. + ++-------------------+-------+-------------+------------------------------------+ +| Property name | Usage | Value type | Description | ++===================+=======+=============+====================================+ +| ``supports-mpmm`` | O | ```` | If present, indicates that |MPMM| | +| | | | is available on this core. | ++-------------------+-------+-------------+------------------------------------+ + +Example +^^^^^^^ + +An example system offering two cores, one with support for |MPMM| and one +without, can be described as follows: + +.. code-block:: + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0@00000 { + ... + + supports-mpmm; + }; + + cpu1@00100 { + ... + }; + } diff --git a/docs/components/index.rst b/docs/components/index.rst index e46751651..754526daf 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -14,6 +14,7 @@ Components fconf/index firmware-update measured_boot/index + mpmm platform-interrupt-controller-API ras romlib-design diff --git a/docs/components/mpmm.rst b/docs/components/mpmm.rst new file mode 100644 index 000000000..1b1c6d8c7 --- /dev/null +++ b/docs/components/mpmm.rst @@ -0,0 +1,30 @@ +Maximum Power Mitigation Mechanism (MPMM) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +|MPMM| is an optional microarchitectural power management mechanism supported by +some Arm Armv9-A cores, beginning with the Cortex-X2, Cortex-A710 and +Cortex-A510 cores. This mechanism detects and limits high-activity events to +assist in |SoC| processor power domain dynamic power budgeting and limit the +triggering of whole-rail (i.e. clock chopping) responses to overcurrent +conditions. + +|MPMM| is enabled on a per-core basis by the EL3 runtime firmware. The presence +of |MPMM| cannot be determined at runtime by the firmware, and therefore the +platform must expose this information through one of two possible mechanisms: + +- |FCONF|, controlled by the ``ENABLE_MPMM_FCONF`` build option. +- A platform implementation of the ``plat_mpmm_topology`` function (the + default). + +See :ref:`Maximum Power Mitigation Mechanism (MPMM) Bindings` for documentation +on the |FCONF| device tree bindings. + +.. warning:: + + |MPMM| exposes gear metrics through the auxiliary |AMU| counters. An + external power controller can use these metrics to budget SoC power by + limiting the number of cores that can execute higher-activity workloads or + switching to a different DVFS operating point. When this is the case, the + |AMU| counters that make up the |MPMM| gears must be enabled by the EL3 + runtime firmware - please see :ref:`Activity Monitor Auxiliary Counters` for + documentation on enabling auxiliary |AMU| counters. diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 8a0167b6d..da8d554db 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -265,6 +265,16 @@ Common build options partitioning in EL3, however. Platform initialisation code should configure and use partitions in EL3 as required. This option defaults to ``0``. +- ``ENABLE_MPMM``: Boolean option to enable support for the Maximum Power + Mitigation Mechanism supported by certain Arm cores, which allows the SoC + firmware to detect and limit high activity events to assist in SoC processor + power domain dynamic power budgeting and limit the triggering of whole-rail + (i.e. clock chopping) responses to overcurrent conditions. Defaults to ``0``. + +- ``ENABLE_MPMM_FCONF``: Enables configuration of MPMM through FCONF, which + allows platforms with cores supporting MPMM to describe them via the + ``HW_CONFIG`` device tree blob. Default is 0. + - ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE) support within generic code in TF-A. This option is currently only supported in BL2_AT_EL3, BL31, and BL32 (TSP) for AARCH64 binaries, and in BL32 diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index a70f15e3d..af1514675 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -25,6 +25,7 @@ .. |Linaro| replace:: :term:`Linaro` .. |MMU| replace:: :term:`MMU` .. |MPAM| replace:: :term:`MPAM` +.. |MPMM| replace:: :term:`MPMM` .. |MPIDR| replace:: :term:`MPIDR` .. |MTE| replace:: :term:`MTE` .. |OEN| replace:: :term:`OEN` diff --git a/docs/glossary.rst b/docs/glossary.rst index a062319ce..aeeb133cb 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -92,6 +92,10 @@ You can find additional definitions in the `Arm Glossary`_. MPAM Memory Partitioning And Monitoring. An optional Armv8.4 extension. + MPMM + Maximum Power Mitigation Mechanism, an optional power management mechanism + supported by some Arm Armv9-A cores. + MPIDR Multiprocessor Affinity Register diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 8b362f1cc..5408acf82 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1216,4 +1216,16 @@ #define DSU_CLUSTER_PWR_ON 1 #define DSU_CLUSTER_PWR_MASK U(1) +/******************************************************************************* + * Definitions for CPU Power/Performance Management registers + ******************************************************************************/ + +#define CPUPPMCR_EL3 S3_6_C15_C2_0 +#define CPUPPMCR_EL3_MPMMPINCTL_SHIFT UINT64_C(0) +#define CPUPPMCR_EL3_MPMMPINCTL_MASK UINT64_C(0x1) + +#define CPUMPMMCR_EL3 S3_6_C15_C2_1 +#define CPUMPMMCR_EL3_MPMM_EN_SHIFT UINT64_C(0) +#define CPUMPMMCR_EL3_MPMM_EN_MASK UINT64_C(0x1) + #endif /* ARCH_H */ diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index cae05dc2e..37fa047c3 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -542,6 +542,10 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(hcrx_el2, HCRX_EL2) /* DynamIQ Shared Unit power management */ DEFINE_RENAME_SYSREG_RW_FUNCS(clusterpwrdn_el1, CLUSTERPWRDN_EL1) +/* CPU Power/Performance Management registers */ +DEFINE_RENAME_SYSREG_RW_FUNCS(cpuppmcr_el3, CPUPPMCR_EL3) +DEFINE_RENAME_SYSREG_RW_FUNCS(cpumpmmcr_el3, CPUMPMMCR_EL3) + /* Armv9.2 RME Registers */ DEFINE_RENAME_SYSREG_RW_FUNCS(gptbr_el3, GPTBR_EL3) DEFINE_RENAME_SYSREG_RW_FUNCS(gpccr_el3, GPCCR_EL3) diff --git a/include/lib/fconf/fconf_mpmm_getter.h b/include/lib/fconf/fconf_mpmm_getter.h new file mode 100644 index 000000000..50d991a2f --- /dev/null +++ b/include/lib/fconf/fconf_mpmm_getter.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_MPMM_GETTER_H +#define FCONF_MPMM_GETTER_H + +#include + +#define mpmm__config_getter(id) fconf_mpmm_config.id + +struct fconf_mpmm_config { + const struct mpmm_topology *topology; +}; + +extern struct fconf_mpmm_config fconf_mpmm_config; + +#endif /* FCONF_MPMM_GETTER_H */ diff --git a/include/lib/mpmm/mpmm.h b/include/lib/mpmm/mpmm.h new file mode 100644 index 000000000..955c530e8 --- /dev/null +++ b/include/lib/mpmm/mpmm.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MPMM_H +#define MPMM_H + +#include + +#include + +/* + * Enable the Maximum Power Mitigation Mechanism. + * + * This function will enable MPMM for the current core. The AMU counters + * representing the MPMM gears must have been configured and enabled prior to + * calling this function. + */ +void mpmm_enable(void); + +/* + * MPMM core data. + * + * This structure represents per-core data retrieved from the hardware + * configuration device tree. + */ +struct mpmm_core { + /* + * Whether MPMM is supported. + * + * Cores with support for MPMM offer one or more auxiliary AMU counters + * representing MPMM gears. + */ + bool supported; +}; + +/* + * MPMM topology. + * + * This topology structure describes the system-wide representation of the + * information retrieved from the hardware configuration device tree. + */ +struct mpmm_topology { + struct mpmm_core cores[PLATFORM_CORE_COUNT]; /* Per-core data */ +}; + +#if !ENABLE_MPMM_FCONF +/* + * Retrieve the platform's MPMM topology. A `NULL` return value is treated as a + * non-fatal error, in which case MPMM will not be enabled for any core. + */ +const struct mpmm_topology *plat_mpmm_topology(void); +#endif /* ENABLE_MPMM_FCONF */ + +#endif /* MPMM_H */ diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index f7125204a..35efd21e0 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -23,6 +23,10 @@ # include #endif +#if ENABLE_MPMM +# include +#endif + struct amu_ctx { uint64_t group0_cnts[AMU_GROUP0_MAX_COUNTERS]; #if ENABLE_AMU_AUXILIARY_COUNTERS @@ -273,26 +277,31 @@ void amu_enable(bool el2_unused, cpu_context_t *ctx) /* Initialize FEAT_AMUv1p1 features if present. */ if (id_aa64pfr0_el1_amu >= ID_AA64PFR0_AMU_V1P1) { - return; - } - - if (el2_unused) { - /* Make sure virtual offsets are disabled if EL2 not used. */ - write_hcr_el2_amvoffen(0U); - } + if (el2_unused) { + /* + * Make sure virtual offsets are disabled if EL2 not + * used. + */ + write_hcr_el2_amvoffen(0U); + } #if AMU_RESTRICT_COUNTERS - /* - * FEAT_AMUv1p1 adds a register field to restrict access to group 1 - * counters at all but the highest implemented EL. This is controlled - * with the AMU_RESTRICT_COUNTERS compile time flag, when set, system - * register reads at lower ELs return zero. Reads from the memory - * mapped view are unaffected. - */ - VERBOSE("AMU group 1 counter access restricted.\n"); - write_amcr_el0_cg1rz(1U); + /* + * FEAT_AMUv1p1 adds a register field to restrict access to + * group 1 counters at all but the highest implemented EL. This + * is controlled with the `AMU_RESTRICT_COUNTERS` compile time + * flag, when set, system register reads at lower ELs return + * zero. Reads from the memory mapped view are unaffected. + */ + VERBOSE("AMU group 1 counter access restricted.\n"); + write_amcr_el0_cg1rz(1U); #else - write_amcr_el0_cg1rz(0U); + write_amcr_el0_cg1rz(0U); +#endif + } + +#if ENABLE_MPMM + mpmm_enable(); #endif } @@ -616,6 +625,10 @@ static void *amu_context_restore(const void *arg) } #endif +#if ENABLE_MPMM + mpmm_enable(); +#endif + return (void *)0; } diff --git a/lib/fconf/fconf.mk b/lib/fconf/fconf.mk index 18bcb3590..fb8891031 100644 --- a/lib/fconf/fconf.mk +++ b/lib/fconf/fconf.mk @@ -14,3 +14,6 @@ FCONF_DYN_SOURCES += ${FDT_WRAPPERS_SOURCES} FCONF_AMU_SOURCES := lib/fconf/fconf_amu_getter.c FCONF_AMU_SOURCES += ${FDT_WRAPPERS_SOURCES} + +FCONF_MPMM_SOURCES := lib/fconf/fconf_mpmm_getter.c +FCONF_MPMM_SOURCES += ${FDT_WRAPPERS_SOURCES} diff --git a/lib/fconf/fconf_mpmm_getter.c b/lib/fconf/fconf_mpmm_getter.c new file mode 100644 index 000000000..02a566d5a --- /dev/null +++ b/lib/fconf/fconf_mpmm_getter.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +struct fconf_mpmm_config fconf_mpmm_config; +static struct mpmm_topology fconf_mpmm_topology; + +/* + * Within a `cpu` node, determine support for MPMM via the `supports-mpmm` + * property. + * + * Returns `0` on success, or a negative integer representing an error code. + */ +static int fconf_populate_mpmm_cpu(const void *fdt, int off, uintptr_t mpidr) +{ + int ret, len; + + int core_pos; + struct mpmm_core *core; + + core_pos = plat_core_pos_by_mpidr(mpidr); + if (core_pos < 0) { + return -FDT_ERR_BADVALUE; + } + + core = &fconf_mpmm_topology.cores[core_pos]; + + fdt_getprop(fdt, off, "supports-mpmm", &len); + if (len >= 0) { + core->supported = true; + ret = 0; + } else { + core->supported = false; + ret = len; + } + + return ret; +} + +/* + * Populates the global `fconf_mpmm_config` structure based on what's described + * by the hardware configuration device tree blob. + * + * The device tree is expected to provide a `supports-mpmm` property for each + * `cpu` node, like so: + * + * cpu@0 { + * supports-mpmm; + * }; + * + * This property indicates whether the core implements MPMM, as we cannot detect + * support for it dynamically. + */ +static int fconf_populate_mpmm(uintptr_t config) +{ + int ret = fdtw_for_each_cpu( + (const void *)config, fconf_populate_mpmm_cpu); + if (ret == 0) { + fconf_mpmm_config.topology = &fconf_mpmm_topology; + } else { + ERROR("FCONF: failed to configure MPMM: %d\n", ret); + } + + return ret; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, mpmm, fconf_populate_mpmm); diff --git a/lib/mpmm/mpmm.c b/lib/mpmm/mpmm.c new file mode 100644 index 000000000..a66f2aad3 --- /dev/null +++ b/lib/mpmm/mpmm.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +#if ENABLE_MPMM_FCONF +# include +# include +#endif + +static uint64_t read_cpuppmcr_el3_mpmmpinctl(void) +{ + return (read_cpuppmcr_el3() >> CPUPPMCR_EL3_MPMMPINCTL_SHIFT) & + CPUPPMCR_EL3_MPMMPINCTL_MASK; +} + +static void write_cpumpmmcr_el3_mpmm_en(uint64_t mpmm_en) +{ + uint64_t value = read_cpumpmmcr_el3(); + + value &= ~(CPUMPMMCR_EL3_MPMM_EN_MASK << CPUMPMMCR_EL3_MPMM_EN_SHIFT); + value |= (mpmm_en & CPUMPMMCR_EL3_MPMM_EN_MASK) << + CPUMPMMCR_EL3_MPMM_EN_SHIFT; + + write_cpumpmmcr_el3(value); +} + +static bool mpmm_supported(void) +{ + bool supported = false; + const struct mpmm_topology *topology; + +#if ENABLE_MPMM_FCONF + topology = FCONF_GET_PROPERTY(mpmm, config, topology); +#else + topology = plat_mpmm_topology(); +#endif /* ENABLE_MPMM_FCONF */ + + /* + * For the current core firstly try to find out if the platform + * configuration has claimed support for MPMM, then make sure that MPMM + * is controllable through the system registers. + */ + + if (topology != NULL) { + unsigned int core_pos = plat_my_core_pos(); + + supported = topology->cores[core_pos].supported && + (read_cpuppmcr_el3_mpmmpinctl() == 0U); + } else { + ERROR("MPMM: failed to generate MPMM topology\n"); + } + + return supported; +} + +void mpmm_enable(void) +{ + bool supported = mpmm_supported(); + + if (supported) { + write_cpumpmmcr_el3_mpmm_en(1U); + } +} diff --git a/lib/mpmm/mpmm.mk b/lib/mpmm/mpmm.mk new file mode 100644 index 000000000..826f9253b --- /dev/null +++ b/lib/mpmm/mpmm.mk @@ -0,0 +1,29 @@ +# +# Copyright (c) 2021, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/extensions/amu/amu.mk +include lib/fconf/fconf.mk + +ifneq (${ENABLE_MPMM},0) + ifneq ($(ARCH),aarch64) + $(error MPMM support (`ENABLE_MPMM`) can only be enabled in AArch64 images (`ARCH`)) + endif + + ifeq (${ENABLE_AMU_AUXILIARY_COUNTERS},0) # For MPMM gear AMU counters + $(error MPMM support (`ENABLE_MPM`) requires auxiliary AMU counter support (`ENABLE_AMU_AUXILIARY_COUNTERS`)) + endif +endif + +MPMM_SOURCES := lib/mpmm/mpmm.c +MPMM_SOURCES += ${AMU_SOURCES} + +ifneq (${ENABLE_MPMM_FCONF},0) + ifeq (${ENABLE_MPMM},0) + $(error MPMM FCONF support (`ENABLE_MPMM_FCONF`) requires MPMM support (`ENABLE_MPMM`)) + endif + + MPMM_SOURCES += ${FCONF_MPMM_SOURCES} +endif diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 8705d9247..45f5fa87f 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -96,6 +96,12 @@ DYN_DISABLE_AUTH := 0 # Build option to enable MPAM for lower ELs ENABLE_MPAM_FOR_LOWER_ELS := 0 +# Enable the Maximum Power Mitigation Mechanism on supporting cores. +ENABLE_MPMM := 0 + +# Enable MPMM configuration via FCONF. +ENABLE_MPMM_FCONF := 0 + # Flag to Enable Position Independant support (PIE) ENABLE_PIE := 0 -- cgit v1.2.3 From c19a82bef08df58350f1b6668e0604ff8a5bd46d Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 18 May 2021 18:49:51 +0100 Subject: feat(tc): enable MPMM This change enables MPMM and adds, to the TC firmware configuration device tree, the AMU counters representing the "gears" for the Maximum Power Mitigation Mechanism feature of the Cortex-X2, Cortex-A710 and Cortex-A510: - Gear 0: throttle medium and high bandwidth vector and viruses. - Gear 1: throttle high bandwidth vector and viruses. - Gear 2: throttle power viruses only. This ensures these counters are enabled and context-switched as expected. Change-Id: I6df6e0fe3a5362861aa967a78ab7c34fc4bb8fc3 Signed-off-by: Chris Kay --- fdts/tc.dts | 41 +++++++++++++++++++++++++++++++++++++++++ plat/arm/board/tc/platform.mk | 5 +++++ 2 files changed, 46 insertions(+) diff --git a/fdts/tc.dts b/fdts/tc.dts index 31fcfe2de..13c9e16e4 100644 --- a/fdts/tc.dts +++ b/fdts/tc.dts @@ -79,6 +79,31 @@ }; }; + amus { + amu: amu-0 { + #address-cells = <1>; + #size-cells = <0>; + + mpmm_gear0: counter@0 { + reg = <0>; + + enable-at-el3; + }; + + mpmm_gear1: counter@1 { + reg = <1>; + + enable-at-el3; + }; + + mpmm_gear2: counter@2 { + reg = <2>; + + enable-at-el3; + }; + }; + }; + CPU0:cpu@0 { device_type = "cpu"; compatible = "arm,armv8"; @@ -87,6 +112,8 @@ clocks = <&scmi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <406>; + amu = <&amu>; + supports-mpmm; }; CPU1:cpu@100 { @@ -97,6 +124,8 @@ clocks = <&scmi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <406>; + amu = <&amu>; + supports-mpmm; }; CPU2:cpu@200 { @@ -107,6 +136,8 @@ clocks = <&scmi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <406>; + amu = <&amu>; + supports-mpmm; }; CPU3:cpu@300 { @@ -117,6 +148,8 @@ clocks = <&scmi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <406>; + amu = <&amu>; + supports-mpmm; }; CPU4:cpu@400 { @@ -127,6 +160,8 @@ clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <912>; + amu = <&amu>; + supports-mpmm; }; CPU5:cpu@500 { @@ -137,6 +172,8 @@ clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <912>; + amu = <&amu>; + supports-mpmm; }; CPU6:cpu@600 { @@ -147,6 +184,8 @@ clocks = <&scmi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <912>; + amu = <&amu>; + supports-mpmm; }; CPU7:cpu@700 { @@ -157,6 +196,8 @@ clocks = <&scmi_dvfs 2>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; capacity-dmips-mhz = <1024>; + amu = <&amu>; + supports-mpmm; }; }; diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index f22cdc050..8765fa2e3 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -140,6 +140,11 @@ override CTX_INCLUDE_PAUTH_REGS := 1 override ENABLE_SPE_FOR_LOWER_ELS := 0 override ENABLE_AMU := 1 +override ENABLE_AMU_AUXILIARY_COUNTERS := 1 +override ENABLE_AMU_FCONF := 1 + +override ENABLE_MPMM := 1 +override ENABLE_MPMM_FCONF := 1 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk -- cgit v1.2.3 From b15f7e2c509d45a68b08f5088736ed444a33791f Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 14 Oct 2021 12:32:52 +0100 Subject: docs(maintainers): add Chris Kay to AMU and MPMM Change-Id: I8c775c8cac4fbbb2904952747a9572a71aff37b4 Signed-off-by: Chris Kay --- docs/about/maintainers.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 7db81fcc6..337dde617 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -217,6 +217,8 @@ Activity Monitors Unit (AMU) extensions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :|M|: Alexei Fedorov :|G|: `AlexeiFedorov`_ +:|M|: Chris Kay +:|G|: `CJKay`_ :|F|: lib/extensions/amu/ Memory Partitioning And Monitoring (MPAM) extensions @@ -326,6 +328,13 @@ System Control and Management Interface (SCMI) Server :|F|: drivers/scmi-msg :|F|: include/drivers/scmi\* +Max Power Mitigation Mechanism (MPMM) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: Chris Kay +:|G|: `CJKay`_ +:|F|: include/lib/mpmm/ +:|F|: lib/mpmm/ + Platform Ports ~~~~~~~~~~~~~~ -- cgit v1.2.3 From 3221fce842c0b5aea984bb8dbc1393082bd88a58 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Wed, 20 Oct 2021 15:17:07 +0200 Subject: fix(spmd): revert workaround hafnium as hypervisor This change essentially reverts [1] by removing the BL31 workaround forcing the dtb address when Hafnium is loaded as an Hypervisor. [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/9569 Signed-off-by: Olivier Deprez Change-Id: I302161d027261448113c66b7fafa9c11620b54ef --- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 4 +--- plat/arm/common/arm_bl31_setup.c | 12 ++++-------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index cad888f37..c26b51920 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, ARM Limited. All rights reserved. + * Copyright (c) 2019-2021, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,12 +45,10 @@ }; #endif -#if !defined(SPD_spmd) nt_fw-config { load-address = <0x0 0x80000000>; max-size = <0x200>; id = ; }; -#endif }; }; diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 6472590f3..a6f7df5f4 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -218,6 +218,10 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi * Linux kernel tree, Linux expects the physical address of the device * tree blob (DTB) in x0, while x1-x3 are reserved for future use and * must be 0. + * Repurpose the option to load Hafnium hypervisor in the normal world. + * It expects its manifest address in x0. This is essentially the linux + * dts (passed to the primary VM) by adding 'hypervisor' and chosen + * nodes specifying the Hypervisor configuration. */ #if RESET_TO_BL31 bl33_image_ep_info.args.arg0 = (u_register_t)ARM_PRELOADED_DTB_BASE; @@ -228,14 +232,6 @@ void __init arm_bl31_early_platform_setup(void *from_bl2, uintptr_t soc_fw_confi bl33_image_ep_info.args.arg2 = 0U; bl33_image_ep_info.args.arg3 = 0U; # endif - -#if defined(SPD_spmd) - /* - * Hafnium in normal world expects its manifest address in x0, In CI - * configuration manifest is preloaded at 0x80000000(start of DRAM). - */ - bl33_image_ep_info.args.arg0 = (u_register_t)ARM_DRAM1_BASE; -#endif } void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, -- cgit v1.2.3 From e8a953a9b85806f7324c8c7245435d5b9226c279 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 20 Oct 2021 17:22:32 +0200 Subject: feat(fdts stm32mp1): align DT with latest kernel Update STM32MP1 device tree files with kernel 5.15. Change-Id: Id405a79e18c61e80cd2292a4f87b7b9641df9c82 Signed-off-by: Yann Gautier --- fdts/stm32mp15-bl2.dtsi | 4 -- fdts/stm32mp15-bl32.dtsi | 6 ++- fdts/stm32mp15-pinctrl.dtsi | 103 ++++++++++++++++++++++++++++++++++------ fdts/stm32mp151.dtsi | 8 ++-- fdts/stm32mp157c-ed1.dts | 3 +- fdts/stm32mp157c-ev1.dts | 3 +- fdts/stm32mp157c-lxa-mc1.dts | 16 +------ fdts/stm32mp15xx-dkx.dtsi | 5 +- fdts/stm32mp15xxaa-pinctrl.dtsi | 2 +- fdts/stm32mp15xxab-pinctrl.dtsi | 2 +- fdts/stm32mp15xxac-pinctrl.dtsi | 2 +- fdts/stm32mp15xxad-pinctrl.dtsi | 2 +- 12 files changed, 107 insertions(+), 49 deletions(-) diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi index da95b25de..080b77212 100644 --- a/fdts/stm32mp15-bl2.dtsi +++ b/fdts/stm32mp15-bl2.dtsi @@ -22,10 +22,6 @@ /delete-node/ stgen@5c008000; /delete-node/ i2c@5c009000; /delete-node/ tamp@5c00a000; - - pin-controller@50002000 { - /delete-node/ rtc-out2-rmp-pins-0; - }; }; #if !STM32MP_USE_STM32IMAGE diff --git a/fdts/stm32mp15-bl32.dtsi b/fdts/stm32mp15-bl32.dtsi index f005d563b..ca4bb3ea5 100644 --- a/fdts/stm32mp15-bl32.dtsi +++ b/fdts/stm32mp15-bl32.dtsi @@ -20,8 +20,8 @@ /delete-node/ hash@54002000; /delete-node/ memory-controller@58002000; /delete-node/ spi@58003000; - /delete-node/ sdmmc@58005000; - /delete-node/ sdmmc@58007000; + /delete-node/ mmc@58005000; + /delete-node/ mmc@58007000; /delete-node/ usbphyc@5a006000; /delete-node/ spi@5c001000; /delete-node/ stgen@5c008000; @@ -37,6 +37,8 @@ /delete-node/ sdmmc2-b4-0; /delete-node/ sdmmc2-b4-1; /delete-node/ sdmmc2-d47-0; + /delete-node/ sdmmc2-d47-1; + /delete-node/ sdmmc2-d47-3; /delete-node/ usbotg_hs-0; /delete-node/ usbotg-fs-dp-dm-0; }; diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi index 058cde264..e8e6b9f3f 100644 --- a/fdts/stm32mp15-pinctrl.dtsi +++ b/fdts/stm32mp15-pinctrl.dtsi @@ -86,12 +86,6 @@ }; }; - rtc_out2_rmp_pins_a: rtc-out2-rmp-pins-0 { - pins { - pinmux = ; /* RTC_OUT2_RMP */ - }; - }; - sdmmc1_b4_pins_a: sdmmc1-b4-0 { pins1 { pinmux = , /* SDMMC1_D0 */ @@ -176,6 +170,18 @@ }; }; + sdmmc2_d47_pins_b: sdmmc2-d47-1 { + pins { + pinmux = , /* SDMMC2_D4 */ + , /* SDMMC2_D5 */ + , /* SDMMC2_D6 */ + ; /* SDMMC2_D7 */ + slew-rate = <1>; + drive-push-pull; + bias-disable; + }; + }; + sdmmc2_d47_pins_d: sdmmc2-d47-3 { pins { pinmux = , /* SDMMC2_D4 */ @@ -213,33 +219,89 @@ uart7_pins_a: uart7-0 { pins1 { - pinmux = ; /* UART4_TX */ + pinmux = ; /* UART7_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = , /* UART4_RX */ - , /* UART4_CTS */ - ; /* UART4_RTS */ + pinmux = , /* UART7_RX */ + , /* UART7_CTS */ + ; /* UART7_RTS */ bias-disable; }; }; uart7_pins_b: uart7-1 { pins1 { - pinmux = ; /* USART7_TX */ + pinmux = ; /* UART7_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* UART7_RX */ + bias-disable; + }; + }; + + uart7_pins_c: uart7-2 { + pins1 { + pinmux = ; /* UART7_TX */ bias-disable; drive-push-pull; slew-rate = <0>; }; pins2 { - pinmux = ; /* USART7_RX */ + pinmux = ; /* UART7_RX */ + bias-disable; + }; + }; + + uart8_pins_a: uart8-0 { + pins1 { + pinmux = ; /* UART8_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* UART8_RX */ bias-disable; }; }; usart2_pins_a: usart2-0 { + pins1 { + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ + bias-disable; + }; + }; + + usart2_pins_b: usart2-1 { + pins1 { + pinmux = , /* USART2_TX */ + ; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = , /* USART2_RX */ + ; /* USART2_CTS_NSS */ + bias-disable; + }; + }; + + usart2_pins_c: usart2-2 { pins1 { pinmux = , /* USART2_TX */ ; /* USART2_RTS */ @@ -255,6 +317,19 @@ }; usart3_pins_a: usart3-0 { + pins1 { + pinmux = ; /* USART3_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; /* USART3_RX */ + bias-disable; + }; + }; + + usart3_pins_b: usart3-1 { pins1 { pinmux = , /* USART3_TX */ ; /* USART3_RTS */ @@ -269,7 +344,7 @@ }; }; - usart3_pins_b: usart3-1 { + usart3_pins_c: usart3-2 { pins1 { pinmux = , /* USART3_TX */ ; /* USART3_RTS */ @@ -284,7 +359,7 @@ }; }; - usbotg_hs_pins_a: usbotg_hs-0 { + usbotg_hs_pins_a: usbotg-hs-0 { pins { pinmux = ; /* OTG_ID */ }; diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi index c350c66de..a7c197121 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -174,7 +174,7 @@ }; usbotg_hs: usb-otg@49000000 { - compatible = "st,stm32mp1-hsotg", "snps,dwc2"; + compatible = "st,stm32mp15-hsotg", "snps,dwc2"; reg = <0x49000000 0x10000>; clocks = <&rcc USBO_K>; clock-names = "otg"; @@ -319,7 +319,7 @@ status = "disabled"; }; - sdmmc1: sdmmc@58005000 { + sdmmc1: mmc@58005000 { compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x00253180>; reg = <0x58005000 0x1000>, <0x58006000 0x1000>; @@ -334,7 +334,7 @@ status = "disabled"; }; - sdmmc2: sdmmc@58007000 { + sdmmc2: mmc@58007000 { compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x00253180>; reg = <0x58007000 0x1000>, <0x58008000 0x1000>; @@ -434,7 +434,7 @@ status = "disabled"; }; - bsec: nvmem@5c005000 { + bsec: efuse@5c005000 { compatible = "st,stm32mp15-bsec"; reg = <0x5c005000 0x400>; #address-cells = <1>; diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index a6b98b7d9..d47109678 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -20,7 +20,6 @@ stdout-path = "serial0:115200n8"; }; - memory@c0000000 { device_type = "memory"; reg = <0xC0000000 0x40000000>; @@ -52,7 +51,7 @@ }; &cryp1 { - status="okay"; + status = "okay"; }; &hash1 { diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts index c5d12e3b2..4937514fb 100644 --- a/fdts/stm32mp157c-ev1.dts +++ b/fdts/stm32mp157c-ev1.dts @@ -57,6 +57,7 @@ &usart3 { pinctrl-names = "default"; - pinctrl-0 = <&usart3_pins_a>; + pinctrl-0 = <&usart3_pins_b>; + uart-has-rtscts; status = "disabled"; }; diff --git a/fdts/stm32mp157c-lxa-mc1.dts b/fdts/stm32mp157c-lxa-mc1.dts index 7b8e48127..31f138239 100644 --- a/fdts/stm32mp157c-lxa-mc1.dts +++ b/fdts/stm32mp157c-lxa-mc1.dts @@ -75,7 +75,7 @@ &sdmmc2 { pinctrl-names = "default"; - pinctrl-0 = <&sdmmc2_b4_pins_a &mc1_sdmmc2_d47_pins_b>; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_b>; bus-width = <8>; no-1-8-v; no-sd; @@ -91,17 +91,3 @@ pinctrl-0 = <&uart4_pins_a>; status = "okay"; }; - -&pinctrl { - mc1_sdmmc2_d47_pins_b: mc1-sdmmc2-d47-1 { - pins { - pinmux = , /* SDMMC2_D4 */ - , /* SDMMC2_D5 */ - , /* SDMMC2_D6 */ - ; /* SDMMC2_D7 */ - slew-rate = <1>; - drive-push-pull; - bias-disable; - }; - }; -}; diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi index 52b914b84..d6458a8a2 100644 --- a/fdts/stm32mp15xx-dkx.dtsi +++ b/fdts/stm32mp15xx-dkx.dtsi @@ -141,7 +141,6 @@ regulator-name = "vdd_usb"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-always-on; }; vdda: ldo5 { @@ -319,13 +318,13 @@ &uart7 { pinctrl-names = "default"; - pinctrl-0 = <&uart7_pins_b>; + pinctrl-0 = <&uart7_pins_c>; status = "disabled"; }; &usart3 { pinctrl-names = "default"; - pinctrl-0 = <&usart3_pins_b>; + pinctrl-0 = <&usart3_pins_c>; uart-has-rtscts; status = "disabled"; }; diff --git a/fdts/stm32mp15xxaa-pinctrl.dtsi b/fdts/stm32mp15xxaa-pinctrl.dtsi index 64e566bf8..04f7a43ad 100644 --- a/fdts/stm32mp15xxaa-pinctrl.dtsi +++ b/fdts/stm32mp15xxaa-pinctrl.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) STMicroelectronics 2019 - All Rights Reserved - * Author: Alexandre Torgue + * Author: Alexandre Torgue for STMicroelectronics. */ &pinctrl { diff --git a/fdts/stm32mp15xxab-pinctrl.dtsi b/fdts/stm32mp15xxab-pinctrl.dtsi index d29af8986..328dad140 100644 --- a/fdts/stm32mp15xxab-pinctrl.dtsi +++ b/fdts/stm32mp15xxab-pinctrl.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) STMicroelectronics 2019 - All Rights Reserved - * Author: Alexandre Torgue + * Author: Alexandre Torgue for STMicroelectronics. */ &pinctrl { diff --git a/fdts/stm32mp15xxac-pinctrl.dtsi b/fdts/stm32mp15xxac-pinctrl.dtsi index 5d8199fd1..7eaa245f4 100644 --- a/fdts/stm32mp15xxac-pinctrl.dtsi +++ b/fdts/stm32mp15xxac-pinctrl.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) STMicroelectronics 2019 - All Rights Reserved - * Author: Alexandre Torgue + * Author: Alexandre Torgue for STMicroelectronics. */ &pinctrl { diff --git a/fdts/stm32mp15xxad-pinctrl.dtsi b/fdts/stm32mp15xxad-pinctrl.dtsi index 023f5404c..b63e207de 100644 --- a/fdts/stm32mp15xxad-pinctrl.dtsi +++ b/fdts/stm32mp15xxad-pinctrl.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) STMicroelectronics 2019 - All Rights Reserved - * Author: Alexandre Torgue + * Author: Alexandre Torgue for STMicroelectronics. */ &pinctrl { -- cgit v1.2.3 From 8cafbda6d3da4dc4204c793fb9d0ca307cc566eb Mon Sep 17 00:00:00 2001 From: Nicolas Le Bayon Date: Thu, 25 Feb 2021 11:03:53 +0100 Subject: refactor(fdts stm32mp1): move STM32MP DDR node Move the generic part of DDR node in SOC dtsi file. DDR dtsi files only include the part configured by CubeMX tool. Signed-off-by: Patrick Delaunay Signed-off-by: Nicolas Le Bayon Change-Id: I8c211e9782604da32aeaab98d0ef75fb1cd9c58d --- fdts/stm32mp15-ddr.dtsi | 256 ++++++++++++++++++++++-------------------------- fdts/stm32mp151.dtsi | 18 ++++ 2 files changed, 133 insertions(+), 141 deletions(-) diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi index 4825691f9..e5efd9256 100644 --- a/fdts/stm32mp15-ddr.dtsi +++ b/fdts/stm32mp15-ddr.dtsi @@ -1,153 +1,127 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Copyright (C) 2018-2021, STMicroelectronics - All Rights Reserved */ -/ { - soc { - ddr: ddr@5a003000{ +&ddr { + st,mem-name = DDR_MEM_NAME; + st,mem-speed = ; + st,mem-size = ; - compatible = "st,stm32mp1-ddr"; + st,ctl-reg = < + DDR_MSTR + DDR_MRCTRL0 + DDR_MRCTRL1 + DDR_DERATEEN + DDR_DERATEINT + DDR_PWRCTL + DDR_PWRTMG + DDR_HWLPCTL + DDR_RFSHCTL0 + DDR_RFSHCTL3 + DDR_CRCPARCTL0 + DDR_ZQCTL0 + DDR_DFITMG0 + DDR_DFITMG1 + DDR_DFILPCFG0 + DDR_DFIUPD0 + DDR_DFIUPD1 + DDR_DFIUPD2 + DDR_DFIPHYMSTR + DDR_ODTMAP + DDR_DBG0 + DDR_DBG1 + DDR_DBGCMD + DDR_POISONCFG + DDR_PCCFG + >; - reg = <0x5A003000 0x550 - 0x5A004000 0x234>; + st,ctl-timing = < + DDR_RFSHTMG + DDR_DRAMTMG0 + DDR_DRAMTMG1 + DDR_DRAMTMG2 + DDR_DRAMTMG3 + DDR_DRAMTMG4 + DDR_DRAMTMG5 + DDR_DRAMTMG6 + DDR_DRAMTMG7 + DDR_DRAMTMG8 + DDR_DRAMTMG14 + DDR_ODTCFG + >; - clocks = <&rcc AXIDCG>, - <&rcc DDRC1>, - <&rcc DDRC2>, - <&rcc DDRPHYC>, - <&rcc DDRCAPB>, - <&rcc DDRPHYCAPB>; + st,ctl-map = < + DDR_ADDRMAP1 + DDR_ADDRMAP2 + DDR_ADDRMAP3 + DDR_ADDRMAP4 + DDR_ADDRMAP5 + DDR_ADDRMAP6 + DDR_ADDRMAP9 + DDR_ADDRMAP10 + DDR_ADDRMAP11 + >; - clock-names = "axidcg", - "ddrc1", - "ddrc2", - "ddrphyc", - "ddrcapb", - "ddrphycapb"; + st,ctl-perf = < + DDR_SCHED + DDR_SCHED1 + DDR_PERFHPR1 + DDR_PERFLPR1 + DDR_PERFWR1 + DDR_PCFGR_0 + DDR_PCFGW_0 + DDR_PCFGQOS0_0 + DDR_PCFGQOS1_0 + DDR_PCFGWQOS0_0 + DDR_PCFGWQOS1_0 + DDR_PCFGR_1 + DDR_PCFGW_1 + DDR_PCFGQOS0_1 + DDR_PCFGQOS1_1 + DDR_PCFGWQOS0_1 + DDR_PCFGWQOS1_1 + >; - st,mem-name = DDR_MEM_NAME; - st,mem-speed = ; - st,mem-size = ; + st,phy-reg = < + DDR_PGCR + DDR_ACIOCR + DDR_DXCCR + DDR_DSGCR + DDR_DCR + DDR_ODTCR + DDR_ZQ0CR1 + DDR_DX0GCR + DDR_DX1GCR + DDR_DX2GCR + DDR_DX3GCR + >; - st,ctl-reg = < - DDR_MSTR - DDR_MRCTRL0 - DDR_MRCTRL1 - DDR_DERATEEN - DDR_DERATEINT - DDR_PWRCTL - DDR_PWRTMG - DDR_HWLPCTL - DDR_RFSHCTL0 - DDR_RFSHCTL3 - DDR_CRCPARCTL0 - DDR_ZQCTL0 - DDR_DFITMG0 - DDR_DFITMG1 - DDR_DFILPCFG0 - DDR_DFIUPD0 - DDR_DFIUPD1 - DDR_DFIUPD2 - DDR_DFIPHYMSTR - DDR_ODTMAP - DDR_DBG0 - DDR_DBG1 - DDR_DBGCMD - DDR_POISONCFG - DDR_PCCFG - >; + st,phy-timing = < + DDR_PTR0 + DDR_PTR1 + DDR_PTR2 + DDR_DTPR0 + DDR_DTPR1 + DDR_DTPR2 + DDR_MR0 + DDR_MR1 + DDR_MR2 + DDR_MR3 + >; - st,ctl-timing = < - DDR_RFSHTMG - DDR_DRAMTMG0 - DDR_DRAMTMG1 - DDR_DRAMTMG2 - DDR_DRAMTMG3 - DDR_DRAMTMG4 - DDR_DRAMTMG5 - DDR_DRAMTMG6 - DDR_DRAMTMG7 - DDR_DRAMTMG8 - DDR_DRAMTMG14 - DDR_ODTCFG - >; - - st,ctl-map = < - DDR_ADDRMAP1 - DDR_ADDRMAP2 - DDR_ADDRMAP3 - DDR_ADDRMAP4 - DDR_ADDRMAP5 - DDR_ADDRMAP6 - DDR_ADDRMAP9 - DDR_ADDRMAP10 - DDR_ADDRMAP11 - >; - - st,ctl-perf = < - DDR_SCHED - DDR_SCHED1 - DDR_PERFHPR1 - DDR_PERFLPR1 - DDR_PERFWR1 - DDR_PCFGR_0 - DDR_PCFGW_0 - DDR_PCFGQOS0_0 - DDR_PCFGQOS1_0 - DDR_PCFGWQOS0_0 - DDR_PCFGWQOS1_0 - DDR_PCFGR_1 - DDR_PCFGW_1 - DDR_PCFGQOS0_1 - DDR_PCFGQOS1_1 - DDR_PCFGWQOS0_1 - DDR_PCFGWQOS1_1 - >; - - st,phy-reg = < - DDR_PGCR - DDR_ACIOCR - DDR_DXCCR - DDR_DSGCR - DDR_DCR - DDR_ODTCR - DDR_ZQ0CR1 - DDR_DX0GCR - DDR_DX1GCR - DDR_DX2GCR - DDR_DX3GCR - >; - - st,phy-timing = < - DDR_PTR0 - DDR_PTR1 - DDR_PTR2 - DDR_DTPR0 - DDR_DTPR1 - DDR_DTPR2 - DDR_MR0 - DDR_MR1 - DDR_MR2 - DDR_MR3 - >; - - st,phy-cal = < - DDR_DX0DLLCR - DDR_DX0DQTR - DDR_DX0DQSTR - DDR_DX1DLLCR - DDR_DX1DQTR - DDR_DX1DQSTR - DDR_DX2DLLCR - DDR_DX2DQTR - DDR_DX2DQSTR - DDR_DX3DLLCR - DDR_DX3DQTR - DDR_DX3DQSTR - >; - - status = "okay"; - }; - }; + st,phy-cal = < + DDR_DX0DLLCR + DDR_DX0DQTR + DDR_DX0DQSTR + DDR_DX1DLLCR + DDR_DX1DQTR + DDR_DX1DQSTR + DDR_DX2DLLCR + DDR_DX2DQTR + DDR_DX2DQSTR + DDR_DX3DLLCR + DDR_DX3DQTR + DDR_DX3DQSTR + >; }; diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi index a7c197121..3beabbbb4 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -358,6 +358,24 @@ status = "disabled"; }; + ddr: ddr@5a003000{ + compatible = "st,stm32mp1-ddr"; + reg = <0x5A003000 0x550 0x5A004000 0x234>; + clocks = <&rcc AXIDCG>, + <&rcc DDRC1>, + <&rcc DDRC2>, + <&rcc DDRPHYC>, + <&rcc DDRCAPB>, + <&rcc DDRPHYCAPB>; + clock-names = "axidcg", + "ddrc1", + "ddrc2", + "ddrphyc", + "ddrcapb", + "ddrphycapb"; + status = "okay"; + }; + usbphyc: usbphyc@5a006000 { #address-cells = <1>; #size-cells = <0>; -- cgit v1.2.3 From 4955d08de7aa664387d2e5f690e78b85ac23a402 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 9 Feb 2021 10:40:37 +0100 Subject: fix(fdts stm32mp1): use 'kHz' as kilohertz abbreviation The kilohertz unit abbreviation should read 'kHz' in DDR settings files of stm32mp15. Signed-off-by: Patrick Delaunay Change-Id: Ifa363094f58dd943ef78c653c3e470a216739b41 --- fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 2 +- fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi index c0fc1f772..6ca6293d4 100644 --- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi @@ -15,7 +15,7 @@ * Save Date: 2020.02.20, save Time: 18:45:20 */ -#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000Khz" +#define DDR_MEM_NAME "DDR3-DDR3L 16bits 533000kHz" #define DDR_MEM_SPEED 533000 #define DDR_MEM_SIZE 0x20000000 diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi index fc226d254..548f69a19 100644 --- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi @@ -15,7 +15,7 @@ * Save Date: 2020.02.20, save Time: 18:49:33 */ -#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000Khz" +#define DDR_MEM_NAME "DDR3-DDR3L 32bits 533000kHz" #define DDR_MEM_SPEED 533000 #define DDR_MEM_SIZE 0x40000000 -- cgit v1.2.3 From 4357db5b17ce6ba7357dd99276f34ab497ce60ef Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 16 Dec 2020 18:17:32 +0100 Subject: feat(fdts stm32mp1): delete nodes for non-used boot devices Cleanup the BL2 device tree file by removing the nodes for the devices that are not used to boot, depending on compilation flags. In SDMMC boot, the gain for the dtb file is about 2.3kB. Change-Id: I3ba13e06dd22b52cff96f51db2dac94b532c81ae Signed-off-by: Yann Gautier --- fdts/stm32mp15-bl2.dtsi | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/fdts/stm32mp15-bl2.dtsi b/fdts/stm32mp15-bl2.dtsi index 080b77212..074414bb2 100644 --- a/fdts/stm32mp15-bl2.dtsi +++ b/fdts/stm32mp15-bl2.dtsi @@ -4,6 +4,12 @@ */ / { +#if !STM32MP_EMMC && !STM32MP_SDMMC + aliases { + /delete-property/ mmc0; + }; +#endif + cpus { /delete-node/ cpu@1; }; @@ -13,15 +19,53 @@ soc { /delete-node/ timer@40006000; /delete-node/ timer@44006000; +#if !STM32MP_USB_PROGRAMMER + /delete-node/ usb-otg@49000000; +#endif /delete-node/ pwr_mcu@50001014; /delete-node/ cryp@54001000; /delete-node/ rng@54003000; +#if !STM32MP_RAW_NAND + /delete-node/ memory-controller@58002000; +#endif +#if !STM32MP_SPI_NAND && !STM32MP_SPI_NOR + /delete-node/ spi@58003000; +#endif +#if !STM32MP_EMMC && !STM32MP_SDMMC + /delete-node/ mmc@58005000; + /delete-node/ mmc@58007000; +#endif +#if !STM32MP_USB_PROGRAMMER + /delete-node/ usbphyc@5a006000; +#endif /delete-node/ spi@5c001000; /delete-node/ rtc@5c004000; /delete-node/ etzpc@5c007000; /delete-node/ stgen@5c008000; /delete-node/ i2c@5c009000; /delete-node/ tamp@5c00a000; + + pin-controller@50002000 { +#if !STM32MP_RAW_NAND + /delete-node/ fmc-0; +#endif +#if !STM32MP_SPI_NAND && !STM32MP_SPI_NOR + /delete-node/ qspi-clk-0; + /delete-node/ qspi-bk1-0; + /delete-node/ qspi-bk2-0; +#endif +#if !STM32MP_EMMC && !STM32MP_SDMMC + /delete-node/ sdmmc1-b4-0; + /delete-node/ sdmmc1-dir-0; + /delete-node/ sdmmc2-b4-0; + /delete-node/ sdmmc2-b4-1; + /delete-node/ sdmmc2-d47-0; +#endif +#if !STM32MP_USB_PROGRAMMER + /delete-node/ usbotg_hs-0; + /delete-node/ usbotg-fs-dp-dm-0; +#endif + }; }; #if !STM32MP_USE_STM32IMAGE -- cgit v1.2.3 From 3e881a8834a955f1e552300bdbf1dafd02ea8f1c Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 17 May 2021 11:25:37 +0200 Subject: fix(fdts stm32mp1): set ETH clock on PLL4P on ST boards Set Ethernet source clock on PLL4P. This is required to enable PTP. Signed-off-by: Yann Gautier Change-Id: Ia64fbb681d3f04f2b90f373c5eb044f5daa2836c --- fdts/stm32mp157c-ed1.dts | 2 +- fdts/stm32mp15xx-dkx.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index d47109678..47b2b1a81 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -232,7 +232,7 @@ CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P CLK_SDMMC12_PLL4P CLK_DSI_DSIPLL CLK_STGEN_HSE diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi index d6458a8a2..69b48285a 100644 --- a/fdts/stm32mp15xx-dkx.dtsi +++ b/fdts/stm32mp15xx-dkx.dtsi @@ -222,7 +222,7 @@ CLK_CKPER_HSE CLK_FMC_ACLK CLK_QSPI_ACLK - CLK_ETH_DISABLED + CLK_ETH_PLL4P CLK_SDMMC12_PLL4P CLK_DSI_DSIPLL CLK_STGEN_HSE -- cgit v1.2.3 From cdbbb9f7ecd4687fa52e1c655b631377c24862b9 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Mon, 17 May 2021 11:25:37 +0200 Subject: fix(fdts stm32mp1): update PLL nodes for ED1/EV1 boards Align STM32MP157C-ED1/EV1 boards PLL nodes with what is done for DK boards. Change-Id: I91be408ea1d9b0474caf4965175df33792b7e11e Signed-off-by: Patrick Delaunay Signed-off-by: Yann Gautier --- fdts/stm32mp157c-ed1.dts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index 47b2b1a81..a09c66afa 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -268,25 +268,33 @@ /* VCO = 1300.0 MHz => P = 650 (CPU) */ pll1: st,pll@0 { - cfg = < 2 80 0 0 0 PQR(1,0,0) >; - frac = < 0x800 >; + compatible = "st,stm32mp1-pll"; + reg = <0>; + cfg = <2 80 0 0 0 PQR(1,0,0)>; + frac = <0x800>; }; /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */ pll2: st,pll@1 { - cfg = < 2 65 1 0 0 PQR(1,1,1) >; - frac = < 0x1400 >; + compatible = "st,stm32mp1-pll"; + reg = <1>; + cfg = <2 65 1 0 0 PQR(1,1,1)>; + frac = <0x1400>; }; /* VCO = 417.8 MHz => P = 209, Q = 24, R = 11 */ pll3: st,pll@2 { - cfg = < 1 33 1 16 36 PQR(1,1,1) >; - frac = < 0x1a04 >; + compatible = "st,stm32mp1-pll"; + reg = <2>; + cfg = <1 33 1 16 36 PQR(1,1,1)>; + frac = <0x1a04>; }; /* VCO = 594.0 MHz => P = 99, Q = 74, R = 74 */ pll4: st,pll@3 { - cfg = < 3 98 5 7 7 PQR(1,1,1) >; + compatible = "st,stm32mp1-pll"; + reg = <3>; + cfg = <3 98 5 7 7 PQR(1,1,1)>; }; }; -- cgit v1.2.3 From 88c227374c065e67bbd7d4a778a806a4c099aab5 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Mon, 11 Oct 2021 14:51:11 -0500 Subject: refactor(fvp_r): remove unused files and clean up makefiles This patch removes files that are not used by TF-R as well as removes unused generic files from the TF-R makefile. Signed-off-by: John Powell Change-Id: Idb15ac295dc77fd38735bf2844efdb73e6f7c89b --- include/arch/aarch64/el2_common_macros.S | 38 ++------ lib/xlat_mpu/xlat_mpu_utils.c | 68 ++++++++------ plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c | 91 ------------------- plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S | 17 ---- plat/arm/board/fvp_r/fvp_r_bl1_main.c | 122 +++++++++++--------------- plat/arm/board/fvp_r/fvp_r_common.c | 20 ----- plat/arm/board/fvp_r/fvp_r_context.S | 17 ---- plat/arm/board/fvp_r/fvp_r_debug.S | 3 +- plat/arm/board/fvp_r/fvp_r_def.h | 26 ++---- plat/arm/board/fvp_r/fvp_r_helpers.S | 38 -------- plat/arm/board/fvp_r/fvp_r_pauth_helpers.S | 59 ------------- plat/arm/board/fvp_r/include/plat.ld.S | 11 --- plat/arm/board/fvp_r/include/platform_def.h | 4 - plat/arm/board/fvp_r/platform.mk | 55 +----------- 14 files changed, 110 insertions(+), 459 deletions(-) delete mode 100644 plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c delete mode 100644 plat/arm/board/fvp_r/fvp_r_context.S delete mode 100644 plat/arm/board/fvp_r/fvp_r_pauth_helpers.S delete mode 100644 plat/arm/board/fvp_r/include/plat.ld.S diff --git a/include/arch/aarch64/el2_common_macros.S b/include/arch/aarch64/el2_common_macros.S index c57a1ec3c..7bf480698 100644 --- a/include/arch/aarch64/el2_common_macros.S +++ b/include/arch/aarch64/el2_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -82,10 +82,6 @@ * Initialise MDCR_EL2, setting all fields rather than relying on * hw. Some fields are architecturally UNKNOWN on reset. * - * MDCR_EL2.SDD: Set to one to disable AArch64 Secure self-hosted - * debug. Debug exceptions, other than Breakpoint Instruction - * exceptions, are disabled from all ELs in Secure state. - * * MDCR_EL2.TDOSA: Set to zero so that EL2 and EL2 System register * access to the powerdown debug registers do not trap to EL2. * @@ -97,17 +93,7 @@ * register accesses to all Performance Monitors registers do not trap * to EL2. * - * MDCR_EL2.SCCD: Set to one so that cycle counting by PMCCNTR_EL0 - * is prohibited in Secure state. This bit is RES0 in versions of the - * architecture with FEAT_PMUv3p5 not implemented, setting it to 1 - * doesn't have any effect on them. - * - * MDCR_EL2.MCCD: Set to one so that cycle counting by PMCCNTR_EL0 - * is prohibited in EL2. This bit is RES0 in versions of the - * architecture with FEAT_PMUv3p7 not implemented, setting it to 1 - * doesn't have any effect on them. - * - * MDCR_EL2.SPME: Set to zero so that event counting by the program- + * MDCR_EL2.HPMD: Set to zero so that event counting by the program- * mable counters PMEVCNTR_EL0 is prohibited in Secure state. If * ARMv8.2 Debug is not implemented this bit does not have any effect * on the counters unless there is support for the implementation @@ -115,9 +101,9 @@ * ExternalSecureNoninvasiveDebugEnabled(). * --------------------------------------------------------------------- */ - mov_imm x0, ((MDCR_EL2_RESET_VAL | MDCR_SDD_BIT | \ - MDCR_SPD32(MDCR_SPD32_DISABLE) | MDCR_SCCD_BIT | \ - MDCR_MCCD_BIT) & ~(MDCR_SPME_BIT | MDCR_TDOSA_BIT | \ + mov_imm x0, ((MDCR_EL2_RESET_VAL | \ + MDCR_SPD32(MDCR_SPD32_DISABLE)) \ + & ~(MDCR_EL2_HPMD | MDCR_TDOSA_BIT | \ MDCR_TDA_BIT | MDCR_TPM_BIT)) msr mdcr_el2, x0 @@ -126,17 +112,6 @@ * Initialise PMCR_EL0 setting all fields rather than relying * on hw. Some fields are architecturally UNKNOWN on reset. * - * PMCR_EL0.LP: Set to one so that event counter overflow, that - * is recorded in PMOVSCLR_EL0[0-30], occurs on the increment - * that changes PMEVCNTR_EL0[63] from 1 to 0, when ARMv8.5-PMU - * is implemented. This bit is RES0 in versions of the architecture - * earlier than ARMv8.5, setting it to 1 doesn't have any effect - * on them. - * - * PMCR_EL0.LC: Set to one so that cycle counter overflow, that - * is recorded in PMOVSCLR_EL0[31], occurs on the increment - * that changes PMCCNTR_EL0[63] from 1 to 0. - * * PMCR_EL0.DP: Set to one so that the cycle counter, * PMCCNTR_EL0 does not count when event counting is prohibited. * @@ -146,8 +121,7 @@ * counts on every clock cycle. * --------------------------------------------------------------------- */ - mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_LP_BIT | \ - PMCR_EL0_LC_BIT | PMCR_EL0_DP_BIT) & \ + mov_imm x0, ((PMCR_EL0_RESET_VAL | PMCR_EL0_DP_BIT) & \ ~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT)) msr pmcr_el0, x0 diff --git a/lib/xlat_mpu/xlat_mpu_utils.c b/lib/xlat_mpu/xlat_mpu_utils.c index f305632dd..540087576 100644 --- a/lib/xlat_mpu/xlat_mpu_utils.c +++ b/lib/xlat_mpu/xlat_mpu_utils.c @@ -22,13 +22,13 @@ #warning "xlat_mpu library is currently experimental and its API may change in future." -#if LOG_LEVEL < LOG_LEVEL_VERBOSE - void xlat_mmap_print(__unused const mmap_region_t *mmap) { /* Empty */ } +#if LOG_LEVEL < LOG_LEVEL_VERBOSE + void xlat_tables_print(__unused xlat_ctx_t *ctx) { /* Empty */ @@ -36,36 +36,48 @@ void xlat_tables_print(__unused xlat_ctx_t *ctx) #else /* if LOG_LEVEL >= LOG_LEVEL_VERBOSE */ -static const char *invalid_descriptors_ommited = - "%s(%d invalid descriptors omitted)\n"; - -void xlat_tables_print(xlat_ctx_t *ctx) +static void xlat_tables_print_internal(__unused xlat_ctx_t *ctx) { - const char *xlat_regime_str; - int used_page_tables; + int region_to_use = 0; + uintptr_t region_base; + size_t region_size; + uint64_t prenr_el2_value = 0U; - if (ctx->xlat_regime == EL1_EL0_REGIME) { - xlat_regime_str = "1&0"; - } else if (ctx->xlat_regime == EL2_REGIME) { - xlat_regime_str = "2"; - } else { - assert(ctx->xlat_regime == EL3_REGIME); - xlat_regime_str = "3"; - /* If no EL3 and EL3 tables generated, then need to know. */ - } - VERBOSE("Translation tables state:\n"); - VERBOSE(" Xlat regime: EL%s\n", xlat_regime_str); - VERBOSE(" Max allowed PA: 0x%llx\n", ctx->pa_max_address); - VERBOSE(" Max allowed VA: 0x%lx\n", ctx->va_max_address); - VERBOSE(" Max mapped PA: 0x%llx\n", ctx->max_pa); - VERBOSE(" Max mapped VA: 0x%lx\n", ctx->max_va); + /* + * Keep track of how many invalid descriptors are counted in a row. + * Whenever multiple invalid descriptors are found, only the first one + * is printed, and a line is added to inform about how many descriptors + * have been omitted. + */ - VERBOSE(" Initial lookup level: %u\n", ctx->base_level); - VERBOSE(" Entries @initial lookup level: %u\n", - ctx->base_table_entries); + /* + * TODO: Remove this WARN() and comment when these API calls are more + * completely implemented and tested! + */ + WARN("%s in this early version of xlat_mpu library may not produce reliable results!", + __func__); - xlat_tables_print_internal(ctx, 0U, ctx->base_table, - ctx->base_table_entries, ctx->base_level); + /* + * Sequence through all regions and print those in-use (PRENR has an + * enable bit for each MPU region, 1 for in-use or 0 for unused): + */ + prenr_el2_value = read_prenr_el2(); + for (region_to_use = 0; region_to_use < N_MPU_REGIONS; + region_to_use++) { + if (((prenr_el2_value >> region_to_use) & 1U) == 0U) { + continue; + } + region_base = read_prbar_el2() & PRBAR_PRLAR_ADDR_MASK; + region_size = read_prlar_el2() & PRBAR_PRLAR_ADDR_MASK; + printf("Address: 0x%llx, size: 0x%llx ", + (long long) region_base, + (long long) region_size); + } +} + +void xlat_tables_print(__unused xlat_ctx_t *ctx) +{ + xlat_tables_print_internal(ctx); } #endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */ diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c b/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c deleted file mode 100644 index c6544b45d..000000000 --- a/plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include "../../../../bl1/bl1_private.h" -#include -#include -#include -#include - -#include - - -void cm_prepare_el2_exit(void); - -/* Following contains the cpu context pointers. */ -static void *bl1_cpu_context_ptr[2]; - -void *cm_get_context(uint32_t security_state) -{ - assert(sec_state_is_valid(security_state)); - return bl1_cpu_context_ptr[security_state]; -} - -void cm_set_context(void *context, uint32_t security_state) -{ - assert(sec_state_is_valid(security_state)); - bl1_cpu_context_ptr[security_state] = context; -} - -/******************************************************************************* - * This function prepares the context for Secure/Normal world images. - * Normal world images are transitioned to EL2(if supported) else EL1. - ******************************************************************************/ -void bl1_prepare_next_image(unsigned int image_id) -{ - /* - * Following array will be used for context management. - * There are 2 instances, for the Secure and Non-Secure contexts. - */ - static cpu_context_t bl1_cpu_context[2]; - - unsigned int security_state, mode = MODE_EL1; - image_desc_t *desc; - entry_point_info_t *next_bl_ep; - -#if CTX_INCLUDE_AARCH32_REGS - /* - * Ensure that the build flag to save AArch32 system registers in CPU - * context is not set for AArch64-only platforms. - */ - if (el_implemented(1) == EL_IMPL_A64ONLY) { - ERROR("EL1 supports AArch64-only. Please set build flag %s", - "CTX_INCLUDE_AARCH32_REGS = 0\n"); - panic(); - } -#endif - - /* Get the image descriptor. */ - desc = bl1_plat_get_image_desc(image_id); - assert(desc != NULL); - - /* Get the entry point info. */ - next_bl_ep = &desc->ep_info; - - /* Get the image security state. */ - security_state = GET_SECURITY_STATE(next_bl_ep->h.attr); - - /* Setup the Secure/Non-Secure context if not done already. */ - if (cm_get_context(security_state) == NULL) { - cm_set_context(&bl1_cpu_context[security_state], security_state); - } - /* Prepare the SPSR for the next BL image. */ - next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode, - (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); - - /* Allow platform to make change */ - bl1_plat_set_ep_info(image_id, next_bl_ep); - - /* Prepare context for the next EL */ - cm_prepare_el2_exit(); - - /* Indicate that image is in execution state. */ - desc->state = IMAGE_STATE_EXECUTED; - - print_entry_point_info(next_bl_ep); -} diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S index 19a685c1f..15f4c4349 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S +++ b/plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S @@ -43,14 +43,6 @@ func bl1_entrypoint */ bl bl1_setup -#if ENABLE_PAUTH - /* -------------------------------------------------------------------- - * Program APIAKey_EL1 and enable pointer authentication. - * -------------------------------------------------------------------- - */ - bl pauth_init_enable_el2 -#endif /* ENABLE_PAUTH */ - /* -------------------------------------------------------------------- * Initialize platform and jump to our c-entry point * for this type of reset. @@ -85,15 +77,6 @@ func bl1_run_next_image */ bl clear_all_mpu_regions -#if ENABLE_PAUTH - /* --------------------------------------------- - * Disable pointer authentication before jumping - * to next boot image. - * --------------------------------------------- - */ - bl pauth_disable_el2 -#endif /* ENABLE_PAUTH */ - /* -------------------------------------------------- * Do the transition to next boot image. * -------------------------------------------------- diff --git a/plat/arm/board/fvp_r/fvp_r_bl1_main.c b/plat/arm/board/fvp_r/fvp_r_bl1_main.c index 2fd0e97eb..841a1769a 100644 --- a/plat/arm/board/fvp_r/fvp_r_bl1_main.c +++ b/plat/arm/board/fvp_r/fvp_r_bl1_main.c @@ -25,6 +25,8 @@ #include +void cm_prepare_el2_exit(void); + void bl1_run_next_image(const struct entry_point_info *bl_ep_info); /******************************************************************************* @@ -39,13 +41,6 @@ void bl1_transfer_bl33(void) /* Get the image id of next image to load and run. */ image_id = bl1_plat_get_next_image_id(); -#if ENABLE_PAUTH - /* - * Disable pointer authentication before running next boot image - */ - pauth_disable_el2(); -#endif /* ENABLE_PAUTH */ - #if !ARM_DISABLE_TRUSTED_WDOG /* Disable watchdog before leaving BL1 */ plat_arm_secure_wdt_stop(); @@ -96,12 +91,6 @@ void bl1_load_bl33(void) NOTICE("BL1: Booting BL33\n"); } -static void bl1_load_bl2(void); - -#if ENABLE_PAUTH -uint64_t bl1_apiakey[2]; -#endif - /******************************************************************************* * Helper utility to calculate the BL2 memory layout taking into consideration * the BL1 RW data assuming that it is at the top of the memory layout. @@ -123,6 +112,53 @@ void bl1_calc_bl2_mem_layout(const meminfo_t *bl1_mem_layout, flush_dcache_range((uintptr_t)bl2_mem_layout, sizeof(meminfo_t)); } +/******************************************************************************* + * This function prepares for entry to BL33 + ******************************************************************************/ +void bl1_prepare_next_image(unsigned int image_id) +{ + unsigned int mode = MODE_EL1; + image_desc_t *desc; + entry_point_info_t *next_bl_ep; + +#if CTX_INCLUDE_AARCH32_REGS + /* + * Ensure that the build flag to save AArch32 system registers in CPU + * context is not set for AArch64-only platforms. + */ + if (el_implemented(1) == EL_IMPL_A64ONLY) { + ERROR("EL1 supports AArch64-only. Please set build flag %s", + "CTX_INCLUDE_AARCH32_REGS = 0\n"); + panic(); + } +#endif + + /* Get the image descriptor. */ + desc = bl1_plat_get_image_desc(image_id); + assert(desc != NULL); + + /* Get the entry point info. */ + next_bl_ep = &desc->ep_info; + + /* FVP-R is only secure */ + assert(GET_SECURITY_STATE(next_bl_ep->h.attr) == SECURE); + + /* Prepare the SPSR for the next BL image. */ + next_bl_ep->spsr = (uint32_t)SPSR_64((uint64_t) mode, + (uint64_t)MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS); + + /* Allow platform to make change */ + bl1_plat_set_ep_info(image_id, next_bl_ep); + + /* Prepare context for the next EL */ + cm_prepare_el2_exit(); + + /* Indicate that image is in execution state. */ + desc->state = IMAGE_STATE_EXECUTED; + + print_entry_point_info(next_bl_ep); +} + /******************************************************************************* * Setup function for BL1. ******************************************************************************/ @@ -133,14 +169,6 @@ void bl1_setup(void) /* Perform late platform-specific setup */ bl1_plat_arch_setup(); - -#if CTX_INCLUDE_PAUTH_REGS - /* - * Assert that the ARMv8.3-PAuth registers are present or an access - * fault will be triggered when they are being saved or restored. - */ - assert(is_armv8_3_pauth_present()); -#endif /* CTX_INCLUDE_PAUTH_REGS */ } /******************************************************************************* @@ -199,12 +227,6 @@ void bl1_main(void) /* Perform platform setup in BL1. */ bl1_platform_setup(); -#if ENABLE_PAUTH - /* Store APIAKey_EL1 key */ - bl1_apiakey[0] = read_apiakeylo_el1(); - bl1_apiakey[1] = read_apiakeyhi_el1(); -#endif /* ENABLE_PAUTH */ - /* Get the image id of next image to load and run. */ image_id = bl1_plat_get_next_image_id(); @@ -212,9 +234,7 @@ void bl1_main(void) * We currently interpret any image id other than * BL2_IMAGE_ID as the start of firmware update. */ - if (image_id == BL2_IMAGE_ID) { - bl1_load_bl2(); - } else if (image_id == BL33_IMAGE_ID) { + if (image_id == BL33_IMAGE_ID) { bl1_load_bl33(); } else { NOTICE("BL1-FWU: *******FWU Process Started*******\n"); @@ -227,48 +247,6 @@ void bl1_main(void) bl1_transfer_bl33(); } -/******************************************************************************* - * This function locates and loads the BL2 raw binary image in the trusted SRAM. - * Called by the primary cpu after a cold boot. - * TODO: Add support for alternative image load mechanism e.g using virtio/elf - * loader etc. - ******************************************************************************/ -static void bl1_load_bl2(void) -{ - image_desc_t *desc; - image_info_t *info; - int err; - - /* Get the image descriptor */ - desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); - assert(desc != NULL); - - /* Get the image info */ - info = &desc->image_info; - INFO("BL1: Loading BL2\n"); - - err = bl1_plat_handle_pre_image_load(BL2_IMAGE_ID); - if (err != 0) { - ERROR("Failure in pre image load handling of BL2 (%d)\n", err); - plat_error_handler(err); - } - - err = load_auth_image(BL2_IMAGE_ID, info); - if (err != 0) { - ERROR("Failed to load BL2 firmware.\n"); - plat_error_handler(err); - } - - /* Allow platform to handle image information. */ - err = bl1_plat_handle_post_image_load(BL2_IMAGE_ID); - if (err != 0) { - ERROR("Failure in post image load handling of BL2 (%d)\n", err); - plat_error_handler(err); - } - - NOTICE("BL1: Booting BL2\n"); -} - /******************************************************************************* * Function called just before handing over to the next BL to inform the user * about the boot progress. In debug mode, also print details about the BL diff --git a/plat/arm/board/fvp_r/fvp_r_common.c b/plat/arm/board/fvp_r/fvp_r_common.c index bce943dad..edcf658b5 100644 --- a/plat/arm/board/fvp_r/fvp_r_common.c +++ b/plat/arm/board/fvp_r/fvp_r_common.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -80,7 +79,6 @@ const mmap_region_t plat_arm_mmap[] = { ARM_CASSERT_MMAP -#if FVP_R_INTERCONNECT_DRIVER != FVP_R_CCN static const int fvp_cci400_map[] = { PLAT_FVP_R_CCI400_CLUS0_SL_PORT, PLAT_FVP_R_CCI400_CLUS1_SL_PORT, @@ -103,7 +101,6 @@ static unsigned int get_interconnect_master(void) assert(master < FVP_R_CLUSTER_COUNT); return master; } -#endif /******************************************************************************* * Initialize the platform config for future decision making @@ -198,14 +195,6 @@ void __init fvp_config_setup(void) void __init fvp_interconnect_init(void) { -#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN - if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { - ERROR("Unrecognized CCN variant detected. Only CCN-502 is supported"); - panic(); - } - - plat_arm_interconnect_init(); -#else uintptr_t cci_base = 0U; const int *cci_map = NULL; unsigned int map_size = 0U; @@ -226,14 +215,10 @@ void __init fvp_interconnect_init(void) assert(cci_base != 0U); assert(cci_map != NULL); cci_init(cci_base, cci_map, map_size); -#endif } void fvp_interconnect_enable(void) { -#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN - plat_arm_interconnect_enter_coherency(); -#else unsigned int master; if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | @@ -241,14 +226,10 @@ void fvp_interconnect_enable(void) master = get_interconnect_master(); cci_enable_snoop_dvm_reqs(master); } -#endif } void fvp_interconnect_disable(void) { -#if FVP_R_INTERCONNECT_DRIVER == FVP_R_CCN - plat_arm_interconnect_exit_coherency(); -#else unsigned int master; if ((arm_config.flags & (ARM_CONFIG_FVP_HAS_CCI400 | @@ -256,7 +237,6 @@ void fvp_interconnect_disable(void) master = get_interconnect_master(); cci_disable_snoop_dvm_reqs(master); } -#endif } #if TRUSTED_BOARD_BOOT diff --git a/plat/arm/board/fvp_r/fvp_r_context.S b/plat/arm/board/fvp_r/fvp_r_context.S deleted file mode 100644 index 2746c2e5b..000000000 --- a/plat/arm/board/fvp_r/fvp_r_context.S +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - - .global el2_exit - -/* ------------------------------------------------------------------ - * The mechanism, from el3_exit, is not used in this v8-R64 implementation. - * ------------------------------------------------------------------ - */ -func el2_exit - exception_return -endfunc el2_exit diff --git a/plat/arm/board/fvp_r/fvp_r_debug.S b/plat/arm/board/fvp_r/fvp_r_debug.S index 8db1b093a..88f0a29a0 100644 --- a/plat/arm/board/fvp_r/fvp_r_debug.S +++ b/plat/arm/board/fvp_r/fvp_r_debug.S @@ -41,6 +41,7 @@ el2_panic: _panic_handler: /* Pass to plat_panic_handler the address from where el2_panic was - * called, not the address of the call from el2_panic. */ + * called, not the address of the call from el2_panic. + */ mov x30, x6 b plat_panic_handler diff --git a/plat/arm/board/fvp_r/fvp_r_def.h b/plat/arm/board/fvp_r/fvp_r_def.h index b9f698939..eda39cfb4 100644 --- a/plat/arm/board/fvp_r/fvp_r_def.h +++ b/plat/arm/board/fvp_r/fvp_r_def.h @@ -9,28 +9,18 @@ #include -#ifndef FVP_R_CLUSTER_COUNT -#error "FVP_R_CLUSTER_COUNT is not set in makefile" -#endif - -#ifndef FVP_R_MAX_CPUS_PER_CLUSTER -#error "FVP_R_MAX_CPUS_PER_CLUSTER is not set in makefile" -#endif - -#ifndef FVP_R_MAX_PE_PER_CPU -#error "FVP_R_MAX_PE_PER_CPU is not set in makefile" -#endif - -#define FVP_R_PRIMARY_CPU 0x0 - -/* Defines for the Interconnect build selection */ -#define FVP_R_CCI 1 -#define FVP_R_CCN 2 +/****************************************************************************** + * FVP-R topology constants + *****************************************************************************/ +#define FVP_R_CLUSTER_COUNT 2 +#define FVP_R_MAX_CPUS_PER_CLUSTER 4 +#define FVP_R_MAX_PE_PER_CPU 1 +#define FVP_R_PRIMARY_CPU 0x0 /****************************************************************************** * Definition of platform soc id *****************************************************************************/ -#define FVP_R_SOC_ID 0 +#define FVP_R_SOC_ID 0 /******************************************************************************* * FVP_R memory map related constants diff --git a/plat/arm/board/fvp_r/fvp_r_helpers.S b/plat/arm/board/fvp_r/fvp_r_helpers.S index f7a04d8bc..ba857779a 100644 --- a/plat/arm/board/fvp_r/fvp_r_helpers.S +++ b/plat/arm/board/fvp_r/fvp_r_helpers.S @@ -16,7 +16,6 @@ .globl plat_secondary_cold_boot_setup .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary - .globl plat_arm_calc_core_pos /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); @@ -127,40 +126,3 @@ func plat_is_my_cpu_primary cset w0, eq ret endfunc plat_is_my_cpu_primary - - /* --------------------------------------------------------------------- - * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) - * - * Function to calculate the core position on FVP_R. - * - * (ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER * FVP_R_MAX_PE_PER_CPU) + - * (CPUId * FVP_R_MAX_PE_PER_CPU) + - * ThreadId - * - * which can be simplified as: - * - * ((ClusterId * FVP_R_MAX_CPUS_PER_CLUSTER + CPUId) * FVP_R_MAX_PE_PER_CPU) - * + ThreadId - * --------------------------------------------------------------------- - */ -func plat_arm_calc_core_pos - /* - * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it - * look as if in a multi-threaded implementation. - */ - tst x0, #MPIDR_MT_MASK - lsl x3, x0, #MPIDR_AFFINITY_BITS - csel x3, x3, x0, eq - - /* Extract individual affinity fields from MPIDR */ - ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS - - /* Compute linear position */ - mov x4, #FVP_R_MAX_CPUS_PER_CLUSTER - madd x1, x2, x4, x1 - mov x5, #FVP_R_MAX_PE_PER_CPU - madd x0, x1, x5, x0 - ret -endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S b/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S deleted file mode 100644 index 7e6bc3d15..000000000 --- a/plat/arm/board/fvp_r/fvp_r_pauth_helpers.S +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - - .global pauth_init_enable_el2 - .global pauth_disable_el2 - -/* ------------------------------------------------------------- - * File contains EL2 versions of EL3 funcs in: - * .../lib/extensions/pauth/pauth_helpers.S - * ------------------------------------------------------------- - */ - -/* ------------------------------------------------------------- - * Program APIAKey_EL1 and enable pointer authentication in EL2 - * ------------------------------------------------------------- - */ -func pauth_init_enable_el2 - stp x29, x30, [sp, #-16]! - - /* Initialize platform key */ - bl plat_init_apkey - - /* Program instruction key A used by the Trusted Firmware */ - msr APIAKeyLo_EL1, x0 - msr APIAKeyHi_EL1, x1 - - /* Enable pointer authentication */ - mrs x0, sctlr_el2 - orr x0, x0, #SCTLR_EnIA_BIT - -#if ENABLE_BTI - /* Enable PAC branch type compatibility */ - bic x0, x0, #SCTLR_BT_BIT -#endif - msr sctlr_el2, x0 - isb - - ldp x29, x30, [sp], #16 - ret -endfunc pauth_init_enable_el2 - -/* ------------------------------------------------------------- - * Disable pointer authentication in EL2 - * ------------------------------------------------------------- - */ -func pauth_disable_el2 - mrs x0, sctlr_el2 - bic x0, x0, #SCTLR_EnIA_BIT - msr sctlr_el2, x0 - isb - ret -endfunc pauth_disable_el2 diff --git a/plat/arm/board/fvp_r/include/plat.ld.S b/plat/arm/board/fvp_r/include/plat.ld.S deleted file mode 100644 index e91a5a0f4..000000000 --- a/plat/arm/board/fvp_r/include/plat.ld.S +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef PLAT_LD_S -#define PLAT_LD_S - -#include - -#endif /* PLAT_LD_S */ diff --git a/plat/arm/board/fvp_r/include/platform_def.h b/plat/arm/board/fvp_r/include/platform_def.h index 4a6b4416b..ea3a258f6 100644 --- a/plat/arm/board/fvp_r/include/platform_def.h +++ b/plat/arm/board/fvp_r/include/platform_def.h @@ -210,10 +210,6 @@ #define PLAT_FVP_R_CCI5XX_CLUS0_SL_PORT 5 #define PLAT_FVP_R_CCI5XX_CLUS1_SL_PORT 6 -/* CCN related constants. Only CCN 502 is currently supported */ -#define PLAT_ARM_CCN_BASE UL(0xae000000) -#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP 1, 5, 7, 11 - /* System timer related constants */ #define PLAT_ARM_NSTIMER_FRAME_ID U(1) diff --git a/plat/arm/board/fvp_r/platform.mk b/plat/arm/board/fvp_r/platform.mk index 8f5878fd9..93b5cf246 100644 --- a/plat/arm/board/fvp_r/platform.mk +++ b/plat/arm/board/fvp_r/platform.mk @@ -15,47 +15,12 @@ NEED_BL32 := no override CTX_INCLUDE_AARCH32_REGS := 0 -# Default cluster count for FVP_R -FVP_R_CLUSTER_COUNT := 2 - -# Default number of CPUs per cluster on FVP_R -FVP_R_MAX_CPUS_PER_CLUSTER := 4 - -# Default number of threads per CPU on FVP_R -FVP_R_MAX_PE_PER_CPU := 1 - # Use MPU-based memory management: XLAT_MPU_LIB_V1 := 1 -# Pass FVP_R_CLUSTER_COUNT to the build system. -$(eval $(call add_define,FVP_R_CLUSTER_COUNT)) - -# Pass FVP_R_MAX_CPUS_PER_CLUSTER to the build system. -$(eval $(call add_define,FVP_R_MAX_CPUS_PER_CLUSTER)) - -# Pass FVP_R_MAX_PE_PER_CPU to the build system. -$(eval $(call add_define,FVP_R_MAX_PE_PER_CPU)) - -# Sanity check the cluster count and if FVP_R_CLUSTER_COUNT <= 2, -# choose the CCI driver , else the CCN driver -ifeq ($(FVP_R_CLUSTER_COUNT), 0) -$(error "Incorrect cluster count specified for FVP_R port") -else ifeq ($(FVP_R_CLUSTER_COUNT),$(filter $(FVP_R_CLUSTER_COUNT),1 2)) -FVP_R_INTERCONNECT_DRIVER := FVP_R_CCI -else -FVP_R_INTERCONNECT_DRIVER := FVP_R_CCN -endif - -$(eval $(call add_define,FVP_R_INTERCONNECT_DRIVER)) - -ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCI) +# FVP R will not have more than 2 clusters so just use CCI interconnect FVP_R_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c -else ifeq (${FVP_R_INTERCONNECT_DRIVER}, FVP_R_CCN) -FVP_R_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \ - plat/arm/common/arm_ccn.c -else -$(error "Incorrect CCN driver chosen on FVP_R port") -endif + include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk @@ -64,17 +29,14 @@ PLAT_INCLUDES := -Iplat/arm/board/fvp_r/include FVP_R_BL_COMMON_SOURCES := plat/arm/board/fvp_r/fvp_r_common.c \ plat/arm/board/fvp_r/fvp_r_context_mgmt.c \ - plat/arm/board/fvp_r/fvp_r_context.S \ plat/arm/board/fvp_r/fvp_r_debug.S \ plat/arm/board/fvp_r/fvp_r_err.c \ plat/arm/board/fvp_r/fvp_r_helpers.S \ - plat/arm/board/fvp_r/fvp_r_misc_helpers.S \ - plat/arm/board/fvp_r/fvp_r_pauth_helpers.S + plat/arm/board/fvp_r/fvp_r_misc_helpers.S FVP_R_BL1_SOURCES := plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \ plat/arm/board/fvp_r/fvp_r_bl1_setup.c \ plat/arm/board/fvp_r/fvp_r_io_storage.c \ - plat/arm/board/fvp_r/fvp_r_bl1_context_mgmt.c \ plat/arm/board/fvp_r/fvp_r_bl1_entrypoint.S \ plat/arm/board/fvp_r/fvp_r_bl1_exceptions.S \ plat/arm/board/fvp_r/fvp_r_bl1_main.c @@ -82,17 +44,13 @@ FVP_R_BL1_SOURCES := plat/arm/board/fvp_r/fvp_r_bl1_arch_setup.c \ FVP_R_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S FVP_R_DYNC_CFG_SOURCES := common/fdt_wrappers.c \ - common/uuid.c \ - plat/arm/common/arm_dyn_cfg.c \ - plat/arm/common/arm_dyn_cfg_helpers.c + plat/arm/common/arm_dyn_cfg.c ifeq (${TRUSTED_BOARD_BOOT},1) FVP_R_AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ lib/fconf/fconf_tbbr_getter.c \ - bl1/tbbr/tbbr_img_desc.c \ - plat/arm/common/arm_bl1_fwu.c \ plat/common/tbbr/plat_tbbr.c \ drivers/auth/tbbr/tbbr_cot_bl1_r64.c \ drivers/auth/tbbr/tbbr_cot_common.c \ @@ -125,11 +83,6 @@ override BL1_SOURCES := drivers/arm/sp805/sp805.c \ drivers/io/io_storage.c \ drivers/io/io_semihosting.c \ lib/cpus/aarch64/cpu_helpers.S \ - lib/cpus/errata_report.c \ - lib/cpus/aarch64/dsu_helpers.S \ - lib/el3_runtime/aarch64/context.S \ - lib/el3_runtime/aarch64/context_mgmt.c \ - lib/fconf/fconf.c \ lib/fconf/fconf_dyn_cfg_getter.c \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ -- cgit v1.2.3 From 859bfd8d42341c6dea2b193db79dc4828e074ad7 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 4 Sep 2020 18:20:51 +0200 Subject: feat(drivers/usb): add a USB device stack Add a new USB framework to manage an USB device profile (USBD) based on a peripheral controller driver (PCD). This USB stack can be use to implement any Universal Serial Bus Device Class in TF-A on top of a USB driver defined in the platform. Signed-off-by: Patrick Delaunay Change-Id: I7971ec6d952edec3511157a198e6e5359df4346b --- drivers/usb/usb_device.c | 840 +++++++++++++++++++++++++++++++++++++++++++ include/drivers/usb_device.h | 276 ++++++++++++++ 2 files changed, 1116 insertions(+) create mode 100644 drivers/usb/usb_device.c create mode 100644 include/drivers/usb_device.h diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c new file mode 100644 index 000000000..ce02d4fc4 --- /dev/null +++ b/drivers/usb/usb_device.c @@ -0,0 +1,840 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include + +/* Define for EP address */ +#define EP_DIR_MASK BIT(7) +#define EP_DIR_IN BIT(7) +#define EP_NUM_MASK GENMASK(3, 0) + +#define EP0_IN (0U | EP_DIR_IN) +#define EP0_OUT 0U + +/* USB address between 1 through 127 = 0x7F mask */ +#define ADDRESS_MASK GENMASK(6, 0) + +/* + * Set a STALL condition over an endpoint + * pdev: USB handle + * ep_addr: endpoint address + * return : status + */ +static enum usb_status usb_core_set_stall(struct usb_handle *pdev, uint8_t ep_addr) +{ + struct usbd_ep *ep; + struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; + uint8_t num; + + num = ep_addr & EP_NUM_MASK; + if (num >= USBD_EP_NB) { + return USBD_FAIL; + } + if ((EP_DIR_MASK & ep_addr) == EP_DIR_IN) { + ep = &hpcd->in_ep[num]; + ep->is_in = true; + } else { + ep = &hpcd->out_ep[num]; + ep->is_in = false; + } + ep->num = num; + + pdev->driver->ep_set_stall(hpcd->instance, ep); + if (num == 0U) { + pdev->driver->ep0_out_start(hpcd->instance); + } + + return USBD_OK; +} + +/* + * usb_core_get_desc + * Handle Get Descriptor requests + * pdev : device instance + * req : usb request + */ +static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req) +{ + uint16_t len; + uint8_t *pbuf; + uint8_t desc_type = HIBYTE(req->value); + uint8_t desc_idx = LOBYTE(req->value); + + switch (desc_type) { + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->desc->get_device_desc(&len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + break; + + case USB_DESC_TYPE_STRING: + switch (desc_idx) { + case USBD_IDX_LANGID_STR: + pbuf = pdev->desc->get_lang_id_desc(&len); + break; + + case USBD_IDX_MFC_STR: + pbuf = pdev->desc->get_manufacturer_desc(&len); + break; + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->desc->get_product_desc(&len); + break; + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->desc->get_serial_desc(&len); + break; + + case USBD_IDX_CONFIG_STR: + pbuf = pdev->desc->get_configuration_desc(&len); + break; + + case USBD_IDX_INTERFACE_STR: + pbuf = pdev->desc->get_interface_desc(&len); + break; + + /* For all USER string */ + case USBD_IDX_USER0_STR: + default: + pbuf = pdev->desc->get_usr_desc(desc_idx - USBD_IDX_USER0_STR, &len); + break; + } + break; + + case USB_DESC_TYPE_DEVICE_QUALIFIER: + pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len); + break; + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + break; + + default: + ERROR("Unknown request %i\n", desc_type); + usb_core_ctl_error(pdev); + return; + } + + if ((len != 0U) && (req->length != 0U)) { + len = MIN(len, req->length); + + /* Start the transfer */ + usb_core_transmit_ep0(pdev, pbuf, len); + } +} + +/* + * usb_core_set_config + * Handle Set device configuration request + * pdev : device instance + * req : usb request + */ +static void usb_core_set_config(struct usb_handle *pdev, struct usb_setup_req *req) +{ + static uint8_t cfgidx; + + cfgidx = LOBYTE(req->value); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION) { + usb_core_ctl_error(pdev); + return; + } + + switch (pdev->dev_state) { + case USBD_STATE_ADDRESSED: + if (cfgidx != 0U) { + pdev->dev_config = cfgidx; + pdev->dev_state = USBD_STATE_CONFIGURED; + if (!pdev->class) { + usb_core_ctl_error(pdev); + return; + } + /* Set configuration and Start the Class */ + if (pdev->class->init(pdev, cfgidx) != 0U) { + usb_core_ctl_error(pdev); + return; + } + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + pdev->class->de_init(pdev, cfgidx); + } else if (cfgidx != pdev->dev_config) { + if (pdev->class != NULL) { + usb_core_ctl_error(pdev); + return; + } + /* Clear old configuration */ + pdev->class->de_init(pdev, pdev->dev_config); + /* Set new configuration */ + pdev->dev_config = cfgidx; + /* Set configuration and start the USB class */ + if (pdev->class->init(pdev, cfgidx) != 0U) { + usb_core_ctl_error(pdev); + return; + } + } + break; + + default: + usb_core_ctl_error(pdev); + return; + } + + /* Send status */ + usb_core_transmit_ep0(pdev, NULL, 0U); +} + +/* + * usb_core_get_status + * Handle Get Status request + * pdev : device instance + * req : usb request + */ +static void usb_core_get_status(struct usb_handle *pdev, + struct usb_setup_req *req) +{ + if ((pdev->dev_state != USBD_STATE_ADDRESSED) && + (pdev->dev_state != USBD_STATE_CONFIGURED)) { + usb_core_ctl_error(pdev); + return; + } + + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; + + if (pdev->dev_remote_wakeup != 0U) { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + /* Start the transfer */ + usb_core_transmit_ep0(pdev, (uint8_t *)&pdev->dev_config_status, 2U); +} + +/* + * usb_core_set_address + * Set device address + * pdev : device instance + * req : usb request + */ +static void usb_core_set_address(struct usb_handle *pdev, + struct usb_setup_req *req) +{ + uint8_t dev_addr; + + if ((req->index != 0U) || (req->length != 0U)) { + usb_core_ctl_error(pdev); + return; + } + + dev_addr = req->value & ADDRESS_MASK; + if (pdev->dev_state != USBD_STATE_DEFAULT) { + usb_core_ctl_error(pdev); + return; + } + + pdev->dev_address = dev_addr; + pdev->driver->set_address(((struct pcd_handle *)(pdev->data))->instance, dev_addr); + + /* Send status */ + usb_core_transmit_ep0(pdev, NULL, 0U); + + if (dev_addr != 0U) { + pdev->dev_state = USBD_STATE_ADDRESSED; + } else { + pdev->dev_state = USBD_STATE_DEFAULT; + } +} + +/* + * usb_core_dev_req + * Handle standard usb device requests + * pdev : device instance + * req : usb request + * return : status + */ +static enum usb_status usb_core_dev_req(struct usb_handle *pdev, + struct usb_setup_req *req) +{ + VERBOSE("receive request %i\n", req->b_request); + switch (req->b_request) { + case USB_REQ_GET_DESCRIPTOR: + usb_core_get_desc(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + usb_core_set_config(pdev, req); + break; + + case USB_REQ_GET_STATUS: + usb_core_get_status(pdev, req); + break; + + case USB_REQ_SET_ADDRESS: + usb_core_set_address(pdev, req); + break; + + case USB_REQ_GET_CONFIGURATION: + case USB_REQ_SET_FEATURE: + case USB_REQ_CLEAR_FEATURE: + default: + ERROR("NOT SUPPORTED %i\n", req->b_request); + usb_core_ctl_error(pdev); + break; + } + + return USBD_OK; +} + +/* + * usb_core_itf_req + * Handle standard usb interface requests + * pdev : device instance + * req : usb request + * return : status + */ +static enum usb_status usb_core_itf_req(struct usb_handle *pdev, + struct usb_setup_req *req) +{ + if (pdev->dev_state != USBD_STATE_CONFIGURED) { + usb_core_ctl_error(pdev); + return USBD_OK; + } + + if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) { + pdev->class->setup(pdev, req); + + if (req->length == 0U) { + usb_core_transmit_ep0(pdev, NULL, 0U); + } + } else { + usb_core_ctl_error(pdev); + } + + return USBD_OK; +} + +/* + * usb_core_setup_stage + * Handle the setup stage + * pdev: device instance + * psetup : setup buffer + * return : status + */ +static enum usb_status usb_core_setup_stage(struct usb_handle *pdev, + uint8_t *psetup) +{ + struct usb_setup_req *req = &pdev->request; + + /* Copy setup buffer into req structure */ + req->bm_request = psetup[0]; + req->b_request = psetup[1]; + req->value = psetup[2] + (psetup[3] << 8); + req->index = psetup[4] + (psetup[5] << 8); + req->length = psetup[6] + (psetup[7] << 8); + + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.length; + + switch (pdev->request.bm_request & USB_REQ_RECIPIENT_MASK) { + case USB_REQ_RECIPIENT_DEVICE: + usb_core_dev_req(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + usb_core_itf_req(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + default: + ERROR("receive unsupported request %i", + pdev->request.bm_request & USB_REQ_RECIPIENT_MASK); + usb_core_set_stall(pdev, pdev->request.bm_request & USB_REQ_DIRECTION); + return USBD_FAIL; + } + + return USBD_OK; +} + +/* + * usb_core_data_out + * Handle data OUT stage + * pdev: device instance + * epnum: endpoint index + * pdata: buffer to sent + * return : status + */ +static enum usb_status usb_core_data_out(struct usb_handle *pdev, uint8_t epnum, + uint8_t *pdata) +{ + struct usb_endpoint *pep; + + if (epnum == 0U) { + pep = &pdev->ep_out[0]; + if (pdev->ep0_state == USBD_EP0_DATA_OUT) { + if (pep->rem_length > pep->maxpacket) { + pep->rem_length -= pep->maxpacket; + + usb_core_receive(pdev, 0U, pdata, + MIN(pep->rem_length, + pep->maxpacket)); + } else { + if (pdev->class->ep0_rx_ready && + (pdev->dev_state == USBD_STATE_CONFIGURED)) { + pdev->class->ep0_rx_ready(pdev); + } + + usb_core_transmit_ep0(pdev, NULL, 0U); + } + } + } else if (pdev->class->data_out != NULL && + (pdev->dev_state == USBD_STATE_CONFIGURED)) { + pdev->class->data_out(pdev, epnum); + } + + return USBD_OK; +} + +/* + * usb_core_data_in + * Handle data in stage + * pdev: device instance + * epnum: endpoint index + * pdata: buffer to fill + * return : status + */ +static enum usb_status usb_core_data_in(struct usb_handle *pdev, uint8_t epnum, + uint8_t *pdata) +{ + if (epnum == 0U) { + struct usb_endpoint *pep = &pdev->ep_in[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_IN) { + if (pep->rem_length > pep->maxpacket) { + pep->rem_length -= pep->maxpacket; + + usb_core_transmit(pdev, 0U, pdata, + pep->rem_length); + + /* Prepare EP for premature end of transfer */ + usb_core_receive(pdev, 0U, NULL, 0U); + } else { + /* Last packet is MPS multiple, send ZLP packet */ + if ((pep->total_length % pep->maxpacket == 0U) && + (pep->total_length >= pep->maxpacket) && + (pep->total_length < pdev->ep0_data_len)) { + usb_core_transmit(pdev, 0U, NULL, 0U); + + pdev->ep0_data_len = 0U; + + /* Prepare endpoint for premature end of transfer */ + usb_core_receive(pdev, 0U, NULL, 0U); + } else { + if (pdev->class->ep0_tx_sent != NULL && + (pdev->dev_state == + USBD_STATE_CONFIGURED)) { + pdev->class->ep0_tx_sent(pdev); + } + /* Start the transfer */ + usb_core_receive_ep0(pdev, NULL, 0U); + } + } + } + } else if ((pdev->class->data_in != NULL) && + (pdev->dev_state == USBD_STATE_CONFIGURED)) { + pdev->class->data_in(pdev, epnum); + } + + return USBD_OK; +} + +/* + * usb_core_suspend + * Handle suspend event + * pdev : device instance + * return : status + */ +static enum usb_status usb_core_suspend(struct usb_handle *pdev) +{ + INFO("USB Suspend mode\n"); + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; + + return USBD_OK; +} + +/* + * usb_core_resume + * Handle resume event + * pdev : device instance + * return : status + */ +static enum usb_status usb_core_resume(struct usb_handle *pdev) +{ + INFO("USB Resume\n"); + pdev->dev_state = pdev->dev_old_state; + + return USBD_OK; +} + +/* + * usb_core_sof + * Handle SOF event + * pdev : device instance + * return : status + */ +static enum usb_status usb_core_sof(struct usb_handle *pdev) +{ + if (pdev->dev_state == USBD_STATE_CONFIGURED) { + if (pdev->class->sof != NULL) { + pdev->class->sof(pdev); + } + } + + return USBD_OK; +} + +/* + * usb_core_disconnect + * Handle device disconnection event + * pdev : device instance + * return : status + */ +static enum usb_status usb_core_disconnect(struct usb_handle *pdev) +{ + /* Free class resources */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->class->de_init(pdev, pdev->dev_config); + + return USBD_OK; +} + +enum usb_status usb_core_handle_it(struct usb_handle *pdev) +{ + uint32_t param = 0U; + uint32_t len = 0U; + struct usbd_ep *ep; + + switch (pdev->driver->it_handler(pdev->data->instance, ¶m)) { + case USB_DATA_OUT: + usb_core_data_out(pdev, param, + pdev->data->out_ep[param].xfer_buff); + break; + + case USB_DATA_IN: + usb_core_data_in(pdev, param, + pdev->data->in_ep[param].xfer_buff); + break; + + case USB_SETUP: + usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup); + break; + + case USB_ENUM_DONE: + break; + + case USB_READ_DATA_PACKET: + ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; + len = (param & USBD_OUT_COUNT_MASK) >> USBD_OUT_COUNT_SHIFT; + pdev->driver->read_packet(pdev->data->instance, + ep->xfer_buff, len); + ep->xfer_buff += len; + ep->xfer_count += len; + break; + + case USB_READ_SETUP_PACKET: + ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK]; + len = (param & USBD_OUT_COUNT_MASK) >> 0x10; + pdev->driver->read_packet(pdev->data->instance, + (uint8_t *)pdev->data->setup, 8); + ep->xfer_count += len; + break; + + case USB_RESET: + pdev->dev_state = USBD_STATE_DEFAULT; + break; + + case USB_RESUME: + if (pdev->data->lpm_state == LPM_L1) { + pdev->data->lpm_state = LPM_L0; + } else { + usb_core_resume(pdev); + } + break; + + case USB_SUSPEND: + usb_core_suspend(pdev); + break; + + case USB_LPM: + if (pdev->data->lpm_state == LPM_L0) { + pdev->data->lpm_state = LPM_L1; + } else { + usb_core_suspend(pdev); + } + break; + + case USB_SOF: + usb_core_sof(pdev); + break; + + case USB_DISCONNECT: + usb_core_disconnect(pdev); + break; + + case USB_WRITE_EMPTY: + pdev->driver->write_empty_tx_fifo(pdev->data->instance, param, + pdev->data->in_ep[param].xfer_len, + (uint32_t *)&pdev->data->in_ep[param].xfer_count, + pdev->data->in_ep[param].maxpacket, + &pdev->data->in_ep[param].xfer_buff); + break; + + case USB_NOTHING: + default: + break; + } + + return USBD_OK; +} + +/* + * usb_core_receive + * Receive an amount of data + * pdev: USB handle + * ep_addr: endpoint address + * buf: pointer to the reception buffer + * len: amount of data to be received + * return : status + */ +enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr, + uint8_t *buf, uint32_t len) +{ + struct usbd_ep *ep; + struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; + uint8_t num; + + num = ep_addr & EP_NUM_MASK; + if (num >= USBD_EP_NB) { + return USBD_FAIL; + } + ep = &hpcd->out_ep[num]; + + /* Setup and start the Xfer */ + ep->xfer_buff = buf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = false; + ep->num = num; + + if (num == 0U) { + pdev->driver->ep0_start_xfer(hpcd->instance, ep); + } else { + pdev->driver->ep_start_xfer(hpcd->instance, ep); + } + + return USBD_OK; +} + +/* + * usb_core_transmit + * Send an amount of data + * pdev: USB handle + * ep_addr: endpoint address + * buf: pointer to the transmission buffer + * len: amount of data to be sent + * return : status + */ +enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr, + uint8_t *buf, uint32_t len) +{ + struct usbd_ep *ep; + struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data; + uint8_t num; + + num = ep_addr & EP_NUM_MASK; + if (num >= USBD_EP_NB) { + return USBD_FAIL; + } + ep = &hpcd->in_ep[num]; + + /* Setup and start the Xfer */ + ep->xfer_buff = buf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = true; + ep->num = num; + + if (num == 0U) { + pdev->driver->ep0_start_xfer(hpcd->instance, ep); + } else { + pdev->driver->ep_start_xfer(hpcd->instance, ep); + } + + return USBD_OK; +} + +/* + * usb_core_receive_ep0 + * Receive an amount of data on ep0 + * pdev: USB handle + * buf: pointer to the reception buffer + * len: amount of data to be received + * return : status + */ +enum usb_status usb_core_receive_ep0(struct usb_handle *pdev, uint8_t *buf, + uint32_t len) +{ + /* Prepare the reception of the buffer over EP0 */ + if (len != 0U) { + pdev->ep0_state = USBD_EP0_DATA_OUT; + } else { + pdev->ep0_state = USBD_EP0_STATUS_OUT; + } + + pdev->ep_out[0].total_length = len; + pdev->ep_out[0].rem_length = len; + + /* Start the transfer */ + return usb_core_receive(pdev, 0U, buf, len); +} + +/* + * usb_core_transmit_ep0 + * Send an amount of data on ep0 + * pdev: USB handle + * buf: pointer to the transmission buffer + * len: amount of data to be sent + * return : status + */ +enum usb_status usb_core_transmit_ep0(struct usb_handle *pdev, uint8_t *buf, + uint32_t len) +{ + /* Set EP0 State */ + if (len != 0U) { + pdev->ep0_state = USBD_EP0_DATA_IN; + } else { + pdev->ep0_state = USBD_EP0_STATUS_IN; + } + + pdev->ep_in[0].total_length = len; + pdev->ep_in[0].rem_length = len; + + /* Start the transfer */ + return usb_core_transmit(pdev, 0U, buf, len); +} + +/* + * usb_core_ctl_error + * Handle USB low level error + * pdev: device instance + * req: usb request + * return : None + */ + +void usb_core_ctl_error(struct usb_handle *pdev) +{ + ERROR("%s : Send an ERROR\n", __func__); + usb_core_set_stall(pdev, EP0_IN); + usb_core_set_stall(pdev, EP0_OUT); +} + +/* + * usb_core_start + * Start the USB device core. + * pdev: Device Handle + * return : USBD Status + */ +enum usb_status usb_core_start(struct usb_handle *pdev) +{ + /* Start the low level driver */ + pdev->driver->start_device(pdev->data->instance); + + return USBD_OK; +} + +/* + * usb_core_stop + * Stop the USB device core. + * pdev: Device Handle + * return : USBD Status + */ +enum usb_status usb_core_stop(struct usb_handle *pdev) +{ + /* Free class resources */ + pdev->class->de_init(pdev, pdev->dev_config); + + /* Stop the low level driver */ + pdev->driver->stop_device(pdev->data->instance); + + return USBD_OK; +} + +/* + * register_usb_driver + * Stop the USB device core. + * pdev: Device Handle + * pcd_handle: PCD handle + * driver: USB driver + * driver_handle: USB driver handle + * return : USBD Status + */ +enum usb_status register_usb_driver(struct usb_handle *pdev, + struct pcd_handle *pcd_handle, + const struct usb_driver *driver, + void *driver_handle) +{ + uint8_t i; + + assert(pdev != NULL); + assert(pcd_handle != NULL); + assert(driver != NULL); + assert(driver_handle != NULL); + + /* Free class resources */ + pdev->driver = driver; + pdev->data = pcd_handle; + pdev->data->instance = driver_handle; + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->ep0_state = USBD_EP0_IDLE; + + /* Copy endpoint information */ + for (i = 0U; i < USBD_EP_NB; i++) { + pdev->ep_in[i].maxpacket = pdev->data->in_ep[i].maxpacket; + pdev->ep_out[i].maxpacket = pdev->data->out_ep[i].maxpacket; + } + + return USBD_OK; +} + +/* + * register_platform + * Register the USB device core. + * pdev: Device Handle + * plat_call_back: callback + * return : USBD Status + */ +enum usb_status register_platform(struct usb_handle *pdev, + const struct usb_desc *plat_call_back) +{ + assert(pdev != NULL); + assert(plat_call_back != NULL); + + /* Save platform info in class resources */ + pdev->desc = plat_call_back; + + return USBD_OK; +} diff --git a/include/drivers/usb_device.h b/include/drivers/usb_device.h new file mode 100644 index 000000000..e21e3155d --- /dev/null +++ b/include/drivers/usb_device.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef USB_DEVICE_H +#define USB_DEVICE_H + +#include + +#include + +#define USBD_MAX_NUM_INTERFACES 1U +#define USBD_MAX_NUM_CONFIGURATION 1U + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU +#define USB_LEN_DEV_DESC 0x12U +#define USB_LEN_CFG_DESC 0x09U +#define USB_LEN_IF_DESC 0x09U +#define USB_LEN_EP_DESC 0x07U +#define USB_LEN_OTG_DESC 0x03U +#define USB_LEN_LANGID_STR_DESC 0x04U +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U + +#define USBD_IDX_LANGID_STR 0x00U +#define USBD_IDX_MFC_STR 0x01U +#define USBD_IDX_PRODUCT_STR 0x02U +#define USBD_IDX_SERIAL_STR 0x03U +#define USBD_IDX_CONFIG_STR 0x04U +#define USBD_IDX_INTERFACE_STR 0x05U +#define USBD_IDX_USER0_STR 0x06U + +#define USB_REQ_TYPE_STANDARD 0x00U +#define USB_REQ_TYPE_CLASS 0x20U +#define USB_REQ_TYPE_VENDOR 0x40U +#define USB_REQ_TYPE_MASK 0x60U + +#define USB_REQ_RECIPIENT_DEVICE 0x00U +#define USB_REQ_RECIPIENT_INTERFACE 0x01U +#define USB_REQ_RECIPIENT_ENDPOINT 0x02U +#define USB_REQ_RECIPIENT_MASK 0x1FU + +#define USB_REQ_DIRECTION 0x80U + +#define USB_REQ_GET_STATUS 0x00U +#define USB_REQ_CLEAR_FEATURE 0x01U +#define USB_REQ_SET_FEATURE 0x03U +#define USB_REQ_SET_ADDRESS 0x05U +#define USB_REQ_GET_DESCRIPTOR 0x06U +#define USB_REQ_SET_DESCRIPTOR 0x07U +#define USB_REQ_GET_CONFIGURATION 0x08U +#define USB_REQ_SET_CONFIGURATION 0x09U +#define USB_REQ_GET_INTERFACE 0x0AU +#define USB_REQ_SET_INTERFACE 0x0BU +#define USB_REQ_SYNCH_FRAME 0x0CU + +#define USB_DESC_TYPE_DEVICE 0x01U +#define USB_DESC_TYPE_CONFIGURATION 0x02U +#define USB_DESC_TYPE_STRING 0x03U +#define USB_DESC_TYPE_INTERFACE 0x04U +#define USB_DESC_TYPE_ENDPOINT 0x05U +#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_BOS 0x0FU + +#define USB_CONFIG_REMOTE_WAKEUP 2U +#define USB_CONFIG_SELF_POWERED 1U + +#define USB_MAX_EP0_SIZE 64U + +/* Device Status */ +#define USBD_STATE_DEFAULT 1U +#define USBD_STATE_ADDRESSED 2U +#define USBD_STATE_CONFIGURED 3U +#define USBD_STATE_SUSPENDED 4U + +/* EP0 State */ +#define USBD_EP0_IDLE 0U +#define USBD_EP0_SETUP 1U +#define USBD_EP0_DATA_IN 2U +#define USBD_EP0_DATA_OUT 3U +#define USBD_EP0_STATUS_IN 4U +#define USBD_EP0_STATUS_OUT 5U +#define USBD_EP0_STALL 6U + +#define USBD_EP_TYPE_CTRL 0U +#define USBD_EP_TYPE_ISOC 1U +#define USBD_EP_TYPE_BULK 2U +#define USBD_EP_TYPE_INTR 3U + +#define USBD_OUT_EPNUM_MASK GENMASK(15, 0) +#define USBD_OUT_COUNT_MASK GENMASK(31, 16) +#define USBD_OUT_COUNT_SHIFT 16U + +/* Number of EP supported, allow to reduce footprint: default max = 15 */ +#ifndef CONFIG_USBD_EP_NB +#define USBD_EP_NB 15U +#else +#define USBD_EP_NB CONFIG_USBD_EP_NB +#endif + +#define LOBYTE(x) ((uint8_t)((x) & 0x00FF)) +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00) >> 8)) + +struct usb_setup_req { + uint8_t bm_request; + uint8_t b_request; + uint16_t value; + uint16_t index; + uint16_t length; +}; + +struct usb_handle; + +struct usb_class { + uint8_t (*init)(struct usb_handle *pdev, uint8_t cfgidx); + uint8_t (*de_init)(struct usb_handle *pdev, uint8_t cfgidx); + /* Control Endpoints */ + uint8_t (*setup)(struct usb_handle *pdev, struct usb_setup_req *req); + uint8_t (*ep0_tx_sent)(struct usb_handle *pdev); + uint8_t (*ep0_rx_ready)(struct usb_handle *pdev); + /* Class Specific Endpoints */ + uint8_t (*data_in)(struct usb_handle *pdev, uint8_t epnum); + uint8_t (*data_out)(struct usb_handle *pdev, uint8_t epnum); + uint8_t (*sof)(struct usb_handle *pdev); + uint8_t (*iso_in_incomplete)(struct usb_handle *pdev, uint8_t epnum); + uint8_t (*iso_out_incomplete)(struct usb_handle *pdev, uint8_t epnum); +}; + +/* Following USB Device status */ +enum usb_status { + USBD_OK = 0U, + USBD_BUSY, + USBD_FAIL, + USBD_TIMEOUT +}; + +/* Action to do after IT handling */ +enum usb_action { + USB_NOTHING = 0U, + USB_DATA_OUT, + USB_DATA_IN, + USB_SETUP, + USB_ENUM_DONE, + USB_READ_DATA_PACKET, + USB_READ_SETUP_PACKET, + USB_RESET, + USB_RESUME, + USB_SUSPEND, + USB_LPM, + USB_SOF, + USB_DISCONNECT, + USB_WRITE_EMPTY +}; + +/* USB Device descriptors structure */ +struct usb_desc { + uint8_t *(*get_device_desc)(uint16_t *length); + uint8_t *(*get_lang_id_desc)(uint16_t *length); + uint8_t *(*get_manufacturer_desc)(uint16_t *length); + uint8_t *(*get_product_desc)(uint16_t *length); + uint8_t *(*get_serial_desc)(uint16_t *length); + uint8_t *(*get_configuration_desc)(uint16_t *length); + uint8_t *(*get_interface_desc)(uint16_t *length); + uint8_t *(*get_usr_desc)(uint8_t index, uint16_t *length); + uint8_t *(*get_config_desc)(uint16_t *length); + uint8_t *(*get_device_qualifier_desc)(uint16_t *length); +}; + +/* USB Device handle structure */ +struct usb_endpoint { + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; +}; + +/* + * EndPoint descriptor + * num : Endpoint number, between 0 and 15 (limited by USBD_EP_NB) + * is_in: Endpoint direction + * type : Endpoint type + * maxpacket: Endpoint Max packet size: between 0 and 64KB + * xfer_buff: Pointer to transfer buffer + * xfer_len: Current transfer lengt + * hxfer_count: Partial transfer length in case of multi packet transfer + */ +struct usbd_ep { + uint8_t num; + bool is_in; + uint8_t type; + uint32_t maxpacket; + uint8_t *xfer_buff; + uint32_t xfer_len; + uint32_t xfer_count; +}; + +enum pcd_lpm_state { + LPM_L0 = 0x00U, /* on */ + LPM_L1 = 0x01U, /* LPM L1 sleep */ + LPM_L2 = 0x02U, /* suspend */ + LPM_L3 = 0x03U, /* off */ +}; + +/* USB Device descriptors structure */ +struct usb_driver { + enum usb_status (*ep0_out_start)(void *handle); + enum usb_status (*ep_start_xfer)(void *handle, struct usbd_ep *ep); + enum usb_status (*ep0_start_xfer)(void *handle, struct usbd_ep *ep); + enum usb_status (*write_packet)(void *handle, uint8_t *src, + uint8_t ch_ep_num, uint16_t len); + void *(*read_packet)(void *handle, uint8_t *dest, uint16_t len); + enum usb_status (*ep_set_stall)(void *handle, struct usbd_ep *ep); + enum usb_status (*start_device)(void *handle); + enum usb_status (*stop_device)(void *handle); + enum usb_status (*set_address)(void *handle, uint8_t address); + enum usb_status (*write_empty_tx_fifo)(void *handle, + uint32_t epnum, uint32_t xfer_len, + uint32_t *xfer_count, + uint32_t maxpacket, + uint8_t **xfer_buff); + enum usb_action (*it_handler)(void *handle, uint32_t *param); +}; + +/* USB Peripheral Controller Drivers */ +struct pcd_handle { + void *instance; /* Register base address */ + struct usbd_ep in_ep[USBD_EP_NB]; /* IN endpoint parameters */ + struct usbd_ep out_ep[USBD_EP_NB]; /* OUT endpoint parameters */ + uint32_t setup[12]; /* Setup packet buffer */ + enum pcd_lpm_state lpm_state; /* LPM State */ +}; + +/* USB Device handle structure */ +struct usb_handle { + uint8_t id; + uint32_t dev_config; + uint32_t dev_config_status; + struct usb_endpoint ep_in[USBD_EP_NB]; + struct usb_endpoint ep_out[USBD_EP_NB]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint32_t dev_remote_wakeup; + struct usb_setup_req request; + const struct usb_desc *desc; + struct usb_class *class; + void *class_data; + void *user_data; + struct pcd_handle *data; + const struct usb_driver *driver; +}; + +enum usb_status usb_core_handle_it(struct usb_handle *pdev); +enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr, + uint8_t *p_buf, uint32_t len); +enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr, + uint8_t *p_buf, uint32_t len); +enum usb_status usb_core_receive_ep0(struct usb_handle *pdev, uint8_t *p_buf, + uint32_t len); +enum usb_status usb_core_transmit_ep0(struct usb_handle *pdev, uint8_t *p_buf, + uint32_t len); +void usb_core_ctl_error(struct usb_handle *pdev); +enum usb_status usb_core_start(struct usb_handle *pdev); +enum usb_status usb_core_stop(struct usb_handle *pdev); +enum usb_status register_usb_driver(struct usb_handle *pdev, + struct pcd_handle *pcd_handle, + const struct usb_driver *driver, + void *driver_handle); +enum usb_status register_platform(struct usb_handle *pdev, + const struct usb_desc *plat_call_back); + +#endif /* USB_DEVICE_H */ -- cgit v1.2.3 From efbd65fa7b5cf70f20d6b18152741ccdf8a65bb6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 14 Sep 2020 09:38:16 +0200 Subject: feat(plat/st): add a USB DFU stack Add a stack to support the Universal Serial Bus Device Class Specification for Device Firmware Upgrade (USB DFU v1.1). This stack is based on the USB device stack (USBD). Change-Id: I8a56411d184882b6a9e3617c6dfb859086b8f353 Signed-off-by: Patrick Delaunay --- plat/st/common/include/usb_dfu.h | 80 ++++++ plat/st/common/usb_dfu.c | 538 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 618 insertions(+) create mode 100644 plat/st/common/include/usb_dfu.h create mode 100644 plat/st/common/usb_dfu.c diff --git a/plat/st/common/include/usb_dfu.h b/plat/st/common/include/usb_dfu.h new file mode 100644 index 000000000..f7d42455f --- /dev/null +++ b/plat/st/common/include/usb_dfu.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef USB_DFU_H +#define USB_DFU_H + +#include + +#include + +#define DFU_DESCRIPTOR_TYPE 0x21U + +/* Max DFU Packet Size = 1024 bytes */ +#define USBD_DFU_XFER_SIZE 1024U + +#define TRANSFER_SIZE_BYTES(size) \ + ((uint8_t)((size) & 0xFF)), /* XFERSIZEB0 */\ + ((uint8_t)((size) >> 8)) /* XFERSIZEB1 */ + +/* + * helper for descriptor of DFU interface 0 Alternate setting n + * with iInterface = index of string descriptor, assumed Nth user string + */ +#define USBD_DFU_IF_DESC(n) 0x09U, /* Interface Descriptor size */\ + USB_DESC_TYPE_INTERFACE, /* descriptor type */\ + 0x00U, /* Number of Interface */\ + (n), /* Alternate setting */\ + 0x00U, /* bNumEndpoints*/\ + 0xFEU, /* Application Specific Class Code */\ + 0x01U, /* Device Firmware Upgrade Code */\ + 0x02U, /* DFU mode protocol */ \ + USBD_IDX_USER0_STR + (n) /* iInterface */ + +/* DFU1.1 Standard */ +#define USB_DFU_VERSION 0x0110U +#define USB_DFU_ITF_SIZ 9U +#define USB_DFU_DESC_SIZ(itf) (USB_DFU_ITF_SIZ * ((itf) + 2U)) + +/* + * bmAttribute value for DFU: + * bitCanDnload = 1(bit 0) + * bitCanUpload = 1(bit 1) + * bitManifestationTolerant = 1 (bit 2) + * bitWillDetach = 1(bit 3) + * Reserved (bit4-6) + * bitAcceleratedST = 0(bit 7) + */ +#define DFU_BM_ATTRIBUTE 0x0FU + +#define DFU_STATUS_SIZE 6U + +/* Callback for media access */ +struct usb_dfu_media { + int (*upload)(uint8_t alt, uintptr_t *buffer, uint32_t *len, + void *user_data); + int (*download)(uint8_t alt, uintptr_t *buffer, uint32_t *len, + void *user_data); + int (*manifestation)(uint8_t alt, void *user_data); +}; + +/* Internal DFU handle */ +struct usb_dfu_handle { + uint8_t status[DFU_STATUS_SIZE]; + uint8_t dev_state; + uint8_t dev_status; + uint8_t alt_setting; + const struct usb_dfu_media *callback; +}; + +void usb_dfu_register(struct usb_handle *pdev, struct usb_dfu_handle *phandle); + +int usb_dfu_loop(struct usb_handle *pdev, const struct usb_dfu_media *pmedia); + +/* Function provided by plat */ +struct usb_handle *usb_dfu_plat_init(void); + +#endif /* USB_DFU_H */ diff --git a/plat/st/common/usb_dfu.c b/plat/st/common/usb_dfu.c new file mode 100644 index 000000000..8bb099425 --- /dev/null +++ b/plat/st/common/usb_dfu.c @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include + +/* Device states as defined in DFU spec */ +#define STATE_APP_IDLE 0 +#define STATE_APP_DETACH 1 +#define STATE_DFU_IDLE 2 +#define STATE_DFU_DNLOAD_SYNC 3 +#define STATE_DFU_DNLOAD_BUSY 4 +#define STATE_DFU_DNLOAD_IDLE 5 +#define STATE_DFU_MANIFEST_SYNC 6 +#define STATE_DFU_MANIFEST 7 +#define STATE_DFU_MANIFEST_WAIT_RESET 8 +#define STATE_DFU_UPLOAD_IDLE 9 +#define STATE_DFU_ERROR 10 + +/* DFU errors */ +#define DFU_ERROR_NONE 0x00 +#define DFU_ERROR_TARGET 0x01 +#define DFU_ERROR_FILE 0x02 +#define DFU_ERROR_WRITE 0x03 +#define DFU_ERROR_ERASE 0x04 +#define DFU_ERROR_CHECK_ERASED 0x05 +#define DFU_ERROR_PROG 0x06 +#define DFU_ERROR_VERIFY 0x07 +#define DFU_ERROR_ADDRESS 0x08 +#define DFU_ERROR_NOTDONE 0x09 +#define DFU_ERROR_FIRMWARE 0x0A +#define DFU_ERROR_VENDOR 0x0B +#define DFU_ERROR_USB 0x0C +#define DFU_ERROR_POR 0x0D +#define DFU_ERROR_UNKNOWN 0x0E +#define DFU_ERROR_STALLEDPKT 0x0F + +/* DFU request */ +#define DFU_DETACH 0 +#define DFU_DNLOAD 1 +#define DFU_UPLOAD 2 +#define DFU_GETSTATUS 3 +#define DFU_CLRSTATUS 4 +#define DFU_GETSTATE 5 +#define DFU_ABORT 6 + +static bool usb_dfu_detach_req; + +/* + * usb_dfu_init + * Initialize the DFU interface + * pdev: device instance + * cfgidx: Configuration index + * return: status + */ +static uint8_t usb_dfu_init(struct usb_handle *pdev, uint8_t cfgidx) +{ + (void)pdev; + (void)cfgidx; + + /* Nothing to do in this stage */ + return USBD_OK; +} + +/* + * usb_dfu_de_init + * De-Initialize the DFU layer + * pdev: device instance + * cfgidx: Configuration index + * return: status + */ +static uint8_t usb_dfu_de_init(struct usb_handle *pdev, uint8_t cfgidx) +{ + (void)pdev; + (void)cfgidx; + + /* Nothing to do in this stage */ + return USBD_OK; +} + +/* + * usb_dfu_data_in + * handle data IN Stage + * pdev: device instance + * epnum: endpoint index + * return: status + */ +static uint8_t usb_dfu_data_in(struct usb_handle *pdev, uint8_t epnum) +{ + (void)pdev; + (void)epnum; + + return USBD_OK; +} + +/* + * usb_dfu_ep0_rx_ready + * handle EP0 Rx Ready event + * pdev: device + * return: status + */ +static uint8_t usb_dfu_ep0_rx_ready(struct usb_handle *pdev) +{ + (void)pdev; + + return USBD_OK; +} + +/* + * usb_dfu_ep0_tx_ready + * handle EP0 TRx Ready event + * pdev: device instance + * return: status + */ +static uint8_t usb_dfu_ep0_tx_ready(struct usb_handle *pdev) +{ + (void)pdev; + + return USBD_OK; +} + +/* + * usb_dfu_sof + * handle SOF event + * pdev: device instance + * return: status + */ +static uint8_t usb_dfu_sof(struct usb_handle *pdev) +{ + (void)pdev; + + return USBD_OK; +} + +/* + * usb_dfu_iso_in_incomplete + * handle data ISO IN Incomplete event + * pdev: device instance + * epnum: endpoint index + * return: status + */ +static uint8_t usb_dfu_iso_in_incomplete(struct usb_handle *pdev, uint8_t epnum) +{ + (void)pdev; + (void)epnum; + + return USBD_OK; +} + +/* + * usb_dfu_iso_out_incomplete + * handle data ISO OUT Incomplete event + * pdev: device instance + * epnum: endpoint index + * return: status + */ +static uint8_t usb_dfu_iso_out_incomplete(struct usb_handle *pdev, + uint8_t epnum) +{ + (void)pdev; + (void)epnum; + + return USBD_OK; +} + +/* + * usb_dfu_data_out + * handle data OUT Stage + * pdev: device instance + * epnum: endpoint index + * return: status + */ +static uint8_t usb_dfu_data_out(struct usb_handle *pdev, uint8_t epnum) +{ + (void)pdev; + (void)epnum; + + return USBD_OK; +} + +/* + * usb_dfu_detach + * Handles the DFU DETACH request. + * pdev: device instance + * req: pointer to the request structure. + */ +static void usb_dfu_detach(struct usb_handle *pdev, struct usb_setup_req *req) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + INFO("Receive DFU Detach\n"); + + if ((hdfu->dev_state == STATE_DFU_IDLE) || + (hdfu->dev_state == STATE_DFU_DNLOAD_SYNC) || + (hdfu->dev_state == STATE_DFU_DNLOAD_IDLE) || + (hdfu->dev_state == STATE_DFU_MANIFEST_SYNC) || + (hdfu->dev_state == STATE_DFU_UPLOAD_IDLE)) { + /* Update the state machine */ + hdfu->dev_state = STATE_DFU_IDLE; + hdfu->dev_status = DFU_ERROR_NONE; + } + + usb_dfu_detach_req = true; +} + +/* + * usb_dfu_download + * Handles the DFU DNLOAD request. + * pdev: device instance + * req: pointer to the request structure + */ +static void usb_dfu_download(struct usb_handle *pdev, struct usb_setup_req *req) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + uintptr_t data_ptr; + uint32_t length; + int ret; + + /* Data setup request */ + if (req->length > 0) { + /* Unsupported state */ + if ((hdfu->dev_state != STATE_DFU_IDLE) && + (hdfu->dev_state != STATE_DFU_DNLOAD_IDLE)) { + /* Call the error management function (command will be nacked) */ + usb_core_ctl_error(pdev); + return; + } + + /* Get the data address */ + length = req->length; + ret = hdfu->callback->download(hdfu->alt_setting, &data_ptr, + &length, pdev->user_data); + if (ret == 0U) { + /* Update the state machine */ + hdfu->dev_state = STATE_DFU_DNLOAD_SYNC; + /* Start the transfer */ + usb_core_receive_ep0(pdev, (uint8_t *)data_ptr, length); + } else { + usb_core_ctl_error(pdev); + } + } else { + /* End of DNLOAD operation*/ + if (hdfu->dev_state != STATE_DFU_DNLOAD_IDLE) { + /* Call the error management function (command will be nacked) */ + usb_core_ctl_error(pdev); + return; + } + /* End of DNLOAD operation*/ + hdfu->dev_state = STATE_DFU_MANIFEST_SYNC; + ret = hdfu->callback->manifestation(hdfu->alt_setting, pdev->user_data); + if (ret == 0U) { + hdfu->dev_state = STATE_DFU_MANIFEST_SYNC; + } else { + usb_core_ctl_error(pdev); + } + } +} + +/* + * usb_dfu_upload + * Handles the DFU UPLOAD request. + * pdev: instance + * req: pointer to the request structure + */ +static void usb_dfu_upload(struct usb_handle *pdev, struct usb_setup_req *req) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + uintptr_t data_ptr; + uint32_t length; + int ret; + + /* Data setup request */ + if (req->length == 0) { + /* No Data setup request */ + hdfu->dev_state = STATE_DFU_IDLE; + return; + } + + /* Unsupported state */ + if ((hdfu->dev_state != STATE_DFU_IDLE) && (hdfu->dev_state != STATE_DFU_UPLOAD_IDLE)) { + ERROR("UPLOAD : Unsupported State\n"); + /* Call the error management function (command will be nacked) */ + usb_core_ctl_error(pdev); + return; + } + + /* Update the data address */ + length = req->length; + ret = hdfu->callback->upload(hdfu->alt_setting, &data_ptr, &length, pdev->user_data); + if (ret == 0U) { + /* Short frame */ + hdfu->dev_state = (req->length > length) ? STATE_DFU_IDLE : STATE_DFU_UPLOAD_IDLE; + + /* Start the transfer */ + usb_core_transmit_ep0(pdev, (uint8_t *)data_ptr, length); + } else { + ERROR("UPLOAD : bad block %i on alt %i\n", req->value, req->index); + hdfu->dev_state = STATE_DFU_ERROR; + hdfu->dev_status = DFU_ERROR_STALLEDPKT; + + /* Call the error management function (command will be nacked) */ + usb_core_ctl_error(pdev); + } +} + +/* + * usb_dfu_get_status + * Handles the DFU GETSTATUS request. + * pdev: instance + */ +static void usb_dfu_get_status(struct usb_handle *pdev) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + hdfu->status[0] = hdfu->dev_status; /* bStatus */ + hdfu->status[1] = 0; /* bwPollTimeout[3] */ + hdfu->status[2] = 0; + hdfu->status[3] = 0; + hdfu->status[4] = hdfu->dev_state; /* bState */ + hdfu->status[5] = 0; /* iString */ + + /* next step */ + switch (hdfu->dev_state) { + case STATE_DFU_DNLOAD_SYNC: + hdfu->dev_state = STATE_DFU_DNLOAD_IDLE; + break; + case STATE_DFU_MANIFEST_SYNC: + /* the device is 'ManifestationTolerant' */ + hdfu->status[4] = STATE_DFU_MANIFEST; + hdfu->status[1] = 1U; /* bwPollTimeout = 1ms */ + hdfu->dev_state = STATE_DFU_IDLE; + break; + + default: + break; + } + + /* Start the transfer */ + usb_core_transmit_ep0(pdev, (uint8_t *)&hdfu->status[0], sizeof(hdfu->status)); +} + +/* + * usb_dfu_clear_status + * Handles the DFU CLRSTATUS request. + * pdev: device instance + */ +static void usb_dfu_clear_status(struct usb_handle *pdev) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + if (hdfu->dev_state == STATE_DFU_ERROR) { + hdfu->dev_state = STATE_DFU_IDLE; + hdfu->dev_status = DFU_ERROR_NONE; + } else { + /* State Error */ + hdfu->dev_state = STATE_DFU_ERROR; + hdfu->dev_status = DFU_ERROR_UNKNOWN; + } +} + +/* + * usb_dfu_get_state + * Handles the DFU GETSTATE request. + * pdev: device instance + */ +static void usb_dfu_get_state(struct usb_handle *pdev) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + /* Return the current state of the DFU interface */ + usb_core_transmit_ep0(pdev, &hdfu->dev_state, 1); +} + +/* + * usb_dfu_abort + * Handles the DFU ABORT request. + * pdev: device instance + */ +static void usb_dfu_abort(struct usb_handle *pdev) +{ + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + if ((hdfu->dev_state == STATE_DFU_IDLE) || + (hdfu->dev_state == STATE_DFU_DNLOAD_SYNC) || + (hdfu->dev_state == STATE_DFU_DNLOAD_IDLE) || + (hdfu->dev_state == STATE_DFU_MANIFEST_SYNC) || + (hdfu->dev_state == STATE_DFU_UPLOAD_IDLE)) { + hdfu->dev_state = STATE_DFU_IDLE; + hdfu->dev_status = DFU_ERROR_NONE; + } +} + +/* + * usb_dfu_setup + * Handle the DFU specific requests + * pdev: instance + * req: usb requests + * return: status + */ +static uint8_t usb_dfu_setup(struct usb_handle *pdev, struct usb_setup_req *req) +{ + uint8_t *pbuf = NULL; + uint16_t len = 0U; + uint8_t ret = USBD_OK; + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + switch (req->bm_request & USB_REQ_TYPE_MASK) { + case USB_REQ_TYPE_CLASS: + switch (req->b_request) { + case DFU_DNLOAD: + usb_dfu_download(pdev, req); + break; + + case DFU_UPLOAD: + usb_dfu_upload(pdev, req); + break; + + case DFU_GETSTATUS: + usb_dfu_get_status(pdev); + break; + + case DFU_CLRSTATUS: + usb_dfu_clear_status(pdev); + break; + + case DFU_GETSTATE: + usb_dfu_get_state(pdev); + break; + + case DFU_ABORT: + usb_dfu_abort(pdev); + break; + + case DFU_DETACH: + usb_dfu_detach(pdev, req); + break; + + default: + ERROR("unknown request %x on alternate %i\n", + req->b_request, hdfu->alt_setting); + usb_core_ctl_error(pdev); + ret = USBD_FAIL; + break; + } + break; + case USB_REQ_TYPE_STANDARD: + switch (req->b_request) { + case USB_REQ_GET_DESCRIPTOR: + if (HIBYTE(req->value) == DFU_DESCRIPTOR_TYPE) { + pbuf = pdev->desc->get_config_desc(&len); + /* DFU descriptor at the end of the USB */ + pbuf += len - 9U; + len = 9U; + len = MIN(len, req->length); + } + + /* Start the transfer */ + usb_core_transmit_ep0(pdev, pbuf, len); + + break; + + case USB_REQ_GET_INTERFACE: + /* Start the transfer */ + usb_core_transmit_ep0(pdev, (uint8_t *)&hdfu->alt_setting, 1U); + break; + + case USB_REQ_SET_INTERFACE: + hdfu->alt_setting = LOBYTE(req->value); + break; + + default: + usb_core_ctl_error(pdev); + ret = USBD_FAIL; + break; + } + default: + break; + } + + return ret; +} + +static const struct usb_class usb_dfu = { + .init = usb_dfu_init, + .de_init = usb_dfu_de_init, + .setup = usb_dfu_setup, + .ep0_tx_sent = usb_dfu_ep0_tx_ready, + .ep0_rx_ready = usb_dfu_ep0_rx_ready, + .data_in = usb_dfu_data_in, + .data_out = usb_dfu_data_out, + .sof = usb_dfu_sof, + .iso_in_incomplete = usb_dfu_iso_in_incomplete, + .iso_out_incomplete = usb_dfu_iso_out_incomplete, +}; + +void usb_dfu_register(struct usb_handle *pdev, struct usb_dfu_handle *phandle) +{ + pdev->class = (struct usb_class *)&usb_dfu; + pdev->class_data = phandle; + + phandle->dev_state = STATE_DFU_IDLE; + phandle->dev_status = DFU_ERROR_NONE; +} + +int usb_dfu_loop(struct usb_handle *pdev, const struct usb_dfu_media *pmedia) +{ + uint32_t it_count; + enum usb_status ret; + struct usb_dfu_handle *hdfu = (struct usb_dfu_handle *)pdev->class_data; + + hdfu->callback = pmedia; + usb_dfu_detach_req = false; + /* Continue to handle USB core IT to assure complete data transmission */ + it_count = 100U; + + /* DFU infinite loop until DETACH_REQ */ + while (it_count != 0U) { + ret = usb_core_handle_it(pdev); + if (ret != USBD_OK) { + return -EIO; + } + + /* Detach request received */ + if (usb_dfu_detach_req) { + it_count--; + } + } + + return 0; +} -- cgit v1.2.3 From 9a138eb5f29f6747e181a1b3b4199ad57721a3e0 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 14 Sep 2020 09:47:44 +0200 Subject: feat(drivers/st/usb): add device driver for STM32MP1 Add a device driver for Synopsis DWC2 USB IP of STM32MP15x, this USB OTG device is only supported in device mode. Signed-off-by: Patrick Delaunay Change-Id: I90b21f094f6637b85f3ace23a3a3a2f6fd4e0951 --- drivers/st/usb/stm32mp1_usb.c | 1091 +++++++++++++++++++++++++++++++++++++ include/drivers/st/stm32mp1_usb.h | 16 + 2 files changed, 1107 insertions(+) create mode 100644 drivers/st/usb/stm32mp1_usb.c create mode 100644 include/drivers/st/stm32mp1_usb.h diff --git a/drivers/st/usb/stm32mp1_usb.c b/drivers/st/usb/stm32mp1_usb.c new file mode 100644 index 000000000..9a4969036 --- /dev/null +++ b/drivers/st/usb/stm32mp1_usb.c @@ -0,0 +1,1091 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#define USB_OTG_MODE_DEVICE 0U +#define USB_OTG_MODE_HOST 1U +#define USB_OTG_MODE_DRD 2U + +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U + +#define USBD_FIFO_FLUSH_TIMEOUT_US 1000U +#define EP0_FIFO_SIZE 64U + +/* OTG registers offsets */ +#define OTG_GOTGINT 0x004U +#define OTG_GAHBCFG 0x008U +#define OTG_GUSBCFG 0x00CU +#define OTG_GRSTCTL 0x010U +#define OTG_GINTSTS 0x014U +#define OTG_GINTMSK 0x018U +#define OTG_GRXSTSP 0x020U +#define OTG_GLPMCFG 0x054U +#define OTG_DCFG 0x800U +#define OTG_DCTL 0x804U +#define OTG_DSTS 0x808U +#define OTG_DIEPMSK 0x810U +#define OTG_DOEPMSK 0x814U +#define OTG_DAINT 0x818U +#define OTG_DAINTMSK 0x81CU +#define OTG_DIEPEMPMSK 0x834U + +/* Definitions for OTG_DIEPx registers */ +#define OTG_DIEP_BASE 0x900U +#define OTG_DIEP_SIZE 0x20U +#define OTG_DIEPCTL 0x00U +#define OTG_DIEPINT 0x08U +#define OTG_DIEPTSIZ 0x10U +#define OTG_DIEPDMA 0x14U +#define OTG_DTXFSTS 0x18U +#define OTG_DIEP_MAX_NB 9U + +/* Definitions for OTG_DOEPx registers */ +#define OTG_DOEP_BASE 0xB00U +#define OTG_DOEP_SIZE 0x20U +#define OTG_DOEPCTL 0x00U +#define OTG_DOEPINT 0x08U +#define OTG_DOEPTSIZ 0x10U +#define OTG_DOEPDMA 0x14U +#define OTG_D0EP_MAX_NB 9U + +/* Definitions for OTG_DAINT registers */ +#define OTG_DAINT_OUT_MASK GENMASK(31, 16) +#define OTG_DAINT_OUT_SHIFT 16U +#define OTG_DAINT_IN_MASK GENMASK(15, 0) +#define OTG_DAINT_IN_SHIFT 0U + +#define OTG_DAINT_EP0_IN BIT(16) +#define OTG_DAINT_EP0_OUT BIT(0) + +/* Definitions for FIFOs */ +#define OTG_FIFO_BASE 0x1000U +#define OTG_FIFO_SIZE 0x1000U + +/* Bit definitions for OTG_GOTGINT register */ +#define OTG_GOTGINT_SEDET BIT(2) + +/* Bit definitions for OTG_GAHBCFG register */ +#define OTG_GAHBCFG_GINT BIT(0) + +/* Bit definitions for OTG_GUSBCFG register */ +#define OTG_GUSBCFG_TRDT GENMASK(13, 10) +#define OTG_GUSBCFG_TRDT_SHIFT 10U + +#define USBD_HS_TRDT_VALUE 9U + +/* Bit definitions for OTG_GRSTCTL register */ +#define OTG_GRSTCTL_RXFFLSH BIT(4) +#define OTG_GRSTCTL_TXFFLSH BIT(5) +#define OTG_GRSTCTL_TXFNUM_SHIFT 6U + +/* Bit definitions for OTG_GINTSTS register */ +#define OTG_GINTSTS_CMOD BIT(0) +#define OTG_GINTSTS_MMIS BIT(1) +#define OTG_GINTSTS_OTGINT BIT(2) +#define OTG_GINTSTS_SOF BIT(3) +#define OTG_GINTSTS_RXFLVL BIT(4) +#define OTG_GINTSTS_USBSUSP BIT(11) +#define OTG_GINTSTS_USBRST BIT(12) +#define OTG_GINTSTS_ENUMDNE BIT(13) +#define OTG_GINTSTS_IEPINT BIT(18) +#define OTG_GINTSTS_OEPINT BIT(19) +#define OTG_GINTSTS_IISOIXFR BIT(20) +#define OTG_GINTSTS_IPXFR_INCOMPISOOUT BIT(21) +#define OTG_GINTSTS_LPMINT BIT(27) +#define OTG_GINTSTS_SRQINT BIT(30) +#define OTG_GINTSTS_WKUPINT BIT(31) + +/* Bit definitions for OTG_GRXSTSP register */ +#define OTG_GRXSTSP_EPNUM GENMASK(3, 0) +#define OTG_GRXSTSP_BCNT GENMASK(14, 4) +#define OTG_GRXSTSP_BCNT_SHIFT 4U +#define OTG_GRXSTSP_PKTSTS GENMASK(20, 17) +#define OTG_GRXSTSP_PKTSTS_SHIFT 17U + +#define STS_GOUT_NAK 1U +#define STS_DATA_UPDT 2U +#define STS_XFER_COMP 3U +#define STS_SETUP_COMP 4U +#define STS_SETUP_UPDT 6U + +/* Bit definitions for OTG_GLPMCFG register */ +#define OTG_GLPMCFG_BESL GENMASK(5, 2) + +/* Bit definitions for OTG_DCFG register */ +#define OTG_DCFG_DAD GENMASK(10, 4) +#define OTG_DCFG_DAD_SHIFT 4U + +/* Bit definitions for OTG_DCTL register */ +#define OTG_DCTL_RWUSIG BIT(0) +#define OTG_DCTL_SDIS BIT(1) +#define OTG_DCTL_CGINAK BIT(8) + +/* Bit definitions for OTG_DSTS register */ +#define OTG_DSTS_SUSPSTS BIT(0) +#define OTG_DSTS_ENUMSPD_MASK GENMASK(2, 1) +#define OTG_DSTS_FNSOF0 BIT(8) + +#define OTG_DSTS_ENUMSPD(val) ((val) << 1) +#define OTG_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(0U) +#define OTG_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ OTG_DSTS_ENUMSPD(1U) +#define OTG_DSTS_ENUMSPD_LS_PHY_6MHZ OTG_DSTS_ENUMSPD(2U) +#define OTG_DSTS_ENUMSPD_FS_PHY_48MHZ OTG_DSTS_ENUMSPD(3U) + +/* Bit definitions for OTG_DIEPMSK register */ +#define OTG_DIEPMSK_XFRCM BIT(0) +#define OTG_DIEPMSK_EPDM BIT(1) +#define OTG_DIEPMSK_TOM BIT(3) + +/* Bit definitions for OTG_DOEPMSK register */ +#define OTG_DOEPMSK_XFRCM BIT(0) +#define OTG_DOEPMSK_EPDM BIT(1) +#define OTG_DOEPMSK_STUPM BIT(3) + +/* Bit definitions for OTG_DIEPCTLx registers */ +#define OTG_DIEPCTL_MPSIZ GENMASK(10, 0) +#define OTG_DIEPCTL_STALL BIT(21) +#define OTG_DIEPCTL_CNAK BIT(26) +#define OTG_DIEPCTL_SD0PID_SEVNFRM BIT(28) +#define OTG_DIEPCTL_SODDFRM BIT(29) +#define OTG_DIEPCTL_EPDIS BIT(30) +#define OTG_DIEPCTL_EPENA BIT(31) + +/* Bit definitions for OTG_DIEPINTx registers */ +#define OTG_DIEPINT_XFRC BIT(0) +#define OTG_DIEPINT_EPDISD BIT(1) +#define OTG_DIEPINT_TOC BIT(3) +#define OTG_DIEPINT_ITTXFE BIT(4) +#define OTG_DIEPINT_INEPNE BIT(6) +#define OTG_DIEPINT_TXFE BIT(7) +#define OTG_DIEPINT_TXFE_SHIFT 7U + +#define OTG_DIEPINT_MASK (BIT(13) | BIT(11) | GENMASK(9, 0)) + +/* Bit definitions for OTG_DIEPTSIZx registers */ +#define OTG_DIEPTSIZ_XFRSIZ GENMASK(18, 0) +#define OTG_DIEPTSIZ_PKTCNT GENMASK(28, 19) +#define OTG_DIEPTSIZ_PKTCNT_SHIFT 19U +#define OTG_DIEPTSIZ_MCNT_MASK GENMASK(30, 29) +#define OTG_DIEPTSIZ_MCNT_DATA0 BIT(29) + +#define OTG_DIEPTSIZ_PKTCNT_1 BIT(19) + +/* Bit definitions for OTG_DTXFSTSx registers */ +#define OTG_DTXFSTS_INEPTFSAV GENMASK(15, 0) + +/* Bit definitions for OTG_DOEPCTLx registers */ +#define OTG_DOEPCTL_STALL BIT(21) +#define OTG_DOEPCTL_CNAK BIT(26) +#define OTG_DOEPCTL_SD0PID_SEVNFRM BIT(28) /* other than endpoint 0 */ +#define OTG_DOEPCTL_SD1PID_SODDFRM BIT(29) /* other than endpoint 0 */ +#define OTG_DOEPCTL_EPDIS BIT(30) +#define OTG_DOEPCTL_EPENA BIT(31) + +/* Bit definitions for OTG_DOEPTSIZx registers */ +#define OTG_DOEPTSIZ_XFRSIZ GENMASK(18, 0) +#define OTG_DOEPTSIZ_PKTCNT GENMASK(28, 19) +#define OTG_DOEPTSIZ_RXDPID_STUPCNT GENMASK(30, 29) + +/* Bit definitions for OTG_DOEPINTx registers */ +#define OTG_DOEPINT_XFRC BIT(0) +#define OTG_DOEPINT_STUP BIT(3) +#define OTG_DOEPINT_OTEPDIS BIT(4) + +#define OTG_DOEPINT_MASK (GENMASK(15, 12) | GENMASK(9, 8) | GENMASK(6, 0)) + +#define EP_NB 15U +#define EP_ALL 0x10U + +/* + * Flush TX FIFO. + * handle: PCD handle. + * num: FIFO number. + * This parameter can be a value from 1 to 15 or EP_ALL. + * EP_ALL= 0x10 means Flush all TX FIFOs + * return: USB status. + */ +static enum usb_status usb_dwc2_flush_tx_fifo(void *handle, uint32_t num) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US); + + mmio_write_32(usb_base_addr + OTG_GRSTCTL, + OTG_GRSTCTL_TXFFLSH | (uint32_t)(num << OTG_GRSTCTL_TXFNUM_SHIFT)); + + while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) & + OTG_GRSTCTL_TXFFLSH) == OTG_GRSTCTL_TXFFLSH) { + if (timeout_elapsed(timeout)) { + return USBD_TIMEOUT; + } + } + + return USBD_OK; +} + +/* + * Flush RX FIFO. + * handle: PCD handle. + * return: USB status. + */ +static enum usb_status usb_dwc2_flush_rx_fifo(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint64_t timeout = timeout_init_us(USBD_FIFO_FLUSH_TIMEOUT_US); + + mmio_write_32(usb_base_addr + OTG_GRSTCTL, OTG_GRSTCTL_RXFFLSH); + + while ((mmio_read_32(usb_base_addr + OTG_GRSTCTL) & + OTG_GRSTCTL_RXFFLSH) == OTG_GRSTCTL_RXFFLSH) { + if (timeout_elapsed(timeout)) { + return USBD_TIMEOUT; + } + } + + return USBD_OK; +} + +/* + * Return the global USB interrupt status. + * handle: PCD handle. + * return: Interrupt register value. + */ +static uint32_t usb_dwc2_read_int(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + return mmio_read_32(usb_base_addr + OTG_GINTSTS) & + mmio_read_32(usb_base_addr + OTG_GINTMSK); +} + +/* + * Return the USB device OUT endpoints interrupt. + * handle: PCD handle. + * return: Device OUT endpoint interrupts. + */ +static uint32_t usb_dwc2_all_out_ep_int(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + return ((mmio_read_32(usb_base_addr + OTG_DAINT) & + mmio_read_32(usb_base_addr + OTG_DAINTMSK)) & + OTG_DAINT_OUT_MASK) >> OTG_DAINT_OUT_SHIFT; +} + +/* + * Return the USB device IN endpoints interrupt. + * handle: PCD handle. + * return: Device IN endpoint interrupts. + */ +static uint32_t usb_dwc2_all_in_ep_int(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + return ((mmio_read_32(usb_base_addr + OTG_DAINT) & + mmio_read_32(usb_base_addr + OTG_DAINTMSK)) & + OTG_DAINT_IN_MASK) >> OTG_DAINT_IN_SHIFT; +} + +/* + * Return Device OUT EP interrupt register. + * handle: PCD handle. + * epnum: Endpoint number. + * This parameter can be a value from 0 to 15. + * return: Device OUT EP Interrupt register. + */ +static uint32_t usb_dwc2_out_ep_int(void *handle, uint8_t epnum) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + return mmio_read_32(usb_base_addr + OTG_DOEP_BASE + + (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT) & + mmio_read_32(usb_base_addr + OTG_DOEPMSK); +} + +/* + * Return Device IN EP interrupt register. + * handle: PCD handle. + * epnum: Endpoint number. + * This parameter can be a value from 0 to 15. + * return: Device IN EP Interrupt register. + */ +static uint32_t usb_dwc2_in_ep_int(void *handle, uint8_t epnum) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t msk; + uint32_t emp; + + msk = mmio_read_32(usb_base_addr + OTG_DIEPMSK); + emp = mmio_read_32(usb_base_addr + OTG_DIEPEMPMSK); + msk |= ((emp >> epnum) << OTG_DIEPINT_TXFE_SHIFT) & OTG_DIEPINT_TXFE; + + return mmio_read_32(usb_base_addr + OTG_DIEP_BASE + + (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT) & msk; +} + +/* + * Return USB core mode. + * handle: PCD handle. + * return: Core mode. + * This parameter can be 0 (host) or 1 (device). + */ +static uint32_t usb_dwc2_get_mode(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + return mmio_read_32(usb_base_addr + OTG_GINTSTS) & OTG_GINTSTS_CMOD; +} + +/* + * Activate EP0 for detup transactions. + * handle: PCD handle. + * return: USB status. + */ +static enum usb_status usb_dwc2_activate_setup(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE; + + /* Set the MPS of the IN EP based on the enumeration speed */ + mmio_clrbits_32(reg_offset + OTG_DIEPCTL, OTG_DIEPCTL_MPSIZ); + + if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_ENUMSPD_MASK) == + OTG_DSTS_ENUMSPD_LS_PHY_6MHZ) { + mmio_setbits_32(reg_offset + OTG_DIEPCTL, 3U); + } + + mmio_setbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_CGINAK); + + return USBD_OK; +} + +/* + * Prepare the EP0 to start the first control setup. + * handle: Selected device. + * return: USB status. + */ +static enum usb_status usb_dwc2_ep0_out_start(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uintptr_t reg_offset = usb_base_addr + OTG_DIEP_BASE + OTG_DIEPTSIZ; + uint32_t reg_value = 0U; + + /* PKTCNT = 1 and XFRSIZ = 24 bytes for endpoint 0 */ + reg_value |= OTG_DIEPTSIZ_PKTCNT_1; + reg_value |= (EP0_FIFO_SIZE & OTG_DIEPTSIZ_XFRSIZ); + reg_value |= OTG_DOEPTSIZ_RXDPID_STUPCNT; + + mmio_write_32(reg_offset, reg_value); + + return USBD_OK; +} + +/* + * Write a packet into the TX FIFO associated with the EP/channel. + * handle: Selected device. + * src: Pointer to source buffer. + * ch_ep_num: Endpoint or host channel number. + * len: Number of bytes to write. + * return: USB status. + */ +static enum usb_status usb_dwc2_write_packet(void *handle, uint8_t *src, + uint8_t ch_ep_num, uint16_t len) +{ + uint32_t reg_offset; + uint32_t count32b = (len + 3U) / 4U; + uint32_t i; + + reg_offset = (uintptr_t)handle + OTG_FIFO_BASE + + (ch_ep_num * OTG_FIFO_SIZE); + + for (i = 0U; i < count32b; i++) { + uint32_t src_copy = 0U; + uint32_t j; + + /* Data written to FIFO need to be 4 bytes aligned */ + for (j = 0U; j < 4U; j++) { + src_copy += (*(src + j)) << (8U * j); + } + + mmio_write_32(reg_offset, src_copy); + src += 4U; + } + + return USBD_OK; +} + +/* + * Read a packet from the RX FIFO associated with the EP/channel. + * handle: Selected device. + * dst: Destination pointer. + * len: Number of bytes to read. + * return: Pointer to destination buffer. + */ +static void *usb_dwc2_read_packet(void *handle, uint8_t *dest, uint16_t len) +{ + uint32_t reg_offset; + uint32_t count32b = (len + 3U) / 4U; + uint32_t i; + + VERBOSE("read packet length %i to 0x%lx\n", len, (uintptr_t)dest); + + reg_offset = (uintptr_t)handle + OTG_FIFO_BASE; + + for (i = 0U; i < count32b; i++) { + *(uint32_t *)dest = mmio_read_32(reg_offset); + dest += 4U; + dsb(); + } + + return (void *)dest; +} + +/* + * Setup and start a transfer over an EP. + * handle: Selected device + * ep: Pointer to endpoint structure. + * return: USB status. + */ +static enum usb_status usb_dwc2_ep_start_xfer(void *handle, struct usbd_ep *ep) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t reg_offset; + uint32_t reg_value; + uint32_t clear_value; + + if (ep->is_in) { + reg_offset = usb_base_addr + OTG_DIEP_BASE + (ep->num * OTG_DIEP_SIZE); + clear_value = OTG_DIEPTSIZ_PKTCNT | OTG_DIEPTSIZ_XFRSIZ; + if (ep->xfer_len == 0U) { + reg_value = OTG_DIEPTSIZ_PKTCNT_1; + } else { + /* + * Program the transfer size and packet count + * as follows: + * xfersize = N * maxpacket + short_packet + * pktcnt = N + (short_packet exist ? 1 : 0) + */ + reg_value = (OTG_DIEPTSIZ_PKTCNT & + (((ep->xfer_len + ep->maxpacket - 1U) / + ep->maxpacket) << OTG_DIEPTSIZ_PKTCNT_SHIFT)) + | ep->xfer_len; + + if (ep->type == EP_TYPE_ISOC) { + clear_value |= OTG_DIEPTSIZ_MCNT_MASK; + reg_value |= OTG_DIEPTSIZ_MCNT_DATA0; + } + } + + mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, clear_value, reg_value); + + if ((ep->type != EP_TYPE_ISOC) && (ep->xfer_len > 0U)) { + /* Enable the TX FIFO empty interrupt for this EP */ + mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(ep->num)); + } + + /* EP enable, IN data in FIFO */ + reg_value = OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA; + + if (ep->type == EP_TYPE_ISOC) { + if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) { + reg_value |= OTG_DIEPCTL_SODDFRM; + } else { + reg_value |= OTG_DIEPCTL_SD0PID_SEVNFRM; + } + } + + mmio_setbits_32(reg_offset + OTG_DIEPCTL, reg_value); + + if (ep->type == EP_TYPE_ISOC) { + usb_dwc2_write_packet(handle, ep->xfer_buff, ep->num, ep->xfer_len); + } + } else { + reg_offset = usb_base_addr + OTG_DOEP_BASE + (ep->num * OTG_DOEP_SIZE); + /* + * Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + if (ep->xfer_len == 0U) { + reg_value = ep->maxpacket | OTG_DIEPTSIZ_PKTCNT_1; + } else { + uint16_t pktcnt = (ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket; + + reg_value = (pktcnt << OTG_DIEPTSIZ_PKTCNT_SHIFT) | + (ep->maxpacket * pktcnt); + } + + mmio_clrsetbits_32(reg_offset + OTG_DOEPTSIZ, + OTG_DOEPTSIZ_XFRSIZ & OTG_DOEPTSIZ_PKTCNT, + reg_value); + + /* EP enable */ + reg_value = OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA; + + if (ep->type == EP_TYPE_ISOC) { + if ((mmio_read_32(usb_base_addr + OTG_DSTS) & OTG_DSTS_FNSOF0) == 0U) { + reg_value |= OTG_DOEPCTL_SD1PID_SODDFRM; + } else { + reg_value |= OTG_DOEPCTL_SD0PID_SEVNFRM; + } + } + + mmio_setbits_32(reg_offset + OTG_DOEPCTL, reg_value); + } + + return USBD_OK; +} + +/* + * Setup and start a transfer over the EP0. + * handle: Selected device. + * ep: Pointer to endpoint structure. + * return: USB status. + */ +static enum usb_status usb_dwc2_ep0_start_xfer(void *handle, struct usbd_ep *ep) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t reg_offset; + uint32_t reg_value; + + if (ep->is_in) { + reg_offset = usb_base_addr + OTG_DIEP_BASE + + (ep->num * OTG_DIEP_SIZE); + + if (ep->xfer_len == 0U) { + reg_value = OTG_DIEPTSIZ_PKTCNT_1; + } else { + /* + * Program the transfer size and packet count + * as follows: + * xfersize = N * maxpacket + short_packet + * pktcnt = N + (short_packet exist ? 1 : 0) + */ + + if (ep->xfer_len > ep->maxpacket) { + ep->xfer_len = ep->maxpacket; + } + + reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->xfer_len; + } + + mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, + OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT, + reg_value); + + /* Enable the TX FIFO empty interrupt for this EP */ + if (ep->xfer_len > 0U) { + mmio_setbits_32(usb_base_addr + OTG_DIEPEMPMSK, + BIT(ep->num)); + } + + /* EP enable, IN data in FIFO */ + mmio_setbits_32(reg_offset + OTG_DIEPCTL, + OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA); + } else { + reg_offset = usb_base_addr + OTG_DOEP_BASE + + (ep->num * OTG_DOEP_SIZE); + + /* + * Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + if (ep->xfer_len > 0U) { + ep->xfer_len = ep->maxpacket; + } + + reg_value = OTG_DIEPTSIZ_PKTCNT_1 | ep->maxpacket; + + mmio_clrsetbits_32(reg_offset + OTG_DIEPTSIZ, + OTG_DIEPTSIZ_XFRSIZ | OTG_DIEPTSIZ_PKTCNT, + reg_value); + + /* EP enable */ + mmio_setbits_32(reg_offset + OTG_DOEPCTL, + OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA); + } + + return USBD_OK; +} + +/* + * Set a stall condition over an EP. + * handle: Selected device. + * ep: Pointer to endpoint structure. + * return: USB status. + */ +static enum usb_status usb_dwc2_ep_set_stall(void *handle, struct usbd_ep *ep) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t reg_offset; + uint32_t reg_value; + + if (ep->is_in) { + reg_offset = usb_base_addr + OTG_DIEP_BASE + + (ep->num * OTG_DIEP_SIZE); + reg_value = mmio_read_32(reg_offset + OTG_DIEPCTL); + + if ((reg_value & OTG_DIEPCTL_EPENA) == 0U) { + reg_value &= ~OTG_DIEPCTL_EPDIS; + } + + reg_value |= OTG_DIEPCTL_STALL; + + mmio_write_32(reg_offset + OTG_DIEPCTL, reg_value); + } else { + reg_offset = usb_base_addr + OTG_DOEP_BASE + + (ep->num * OTG_DOEP_SIZE); + reg_value = mmio_read_32(reg_offset + OTG_DOEPCTL); + + if ((reg_value & OTG_DOEPCTL_EPENA) == 0U) { + reg_value &= ~OTG_DOEPCTL_EPDIS; + } + + reg_value |= OTG_DOEPCTL_STALL; + + mmio_write_32(reg_offset + OTG_DOEPCTL, reg_value); + } + + return USBD_OK; +} + +/* + * Stop the USB device mode. + * handle: Selected device. + * return: USB status. + */ +static enum usb_status usb_dwc2_stop_device(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t i; + + /* Disable Int */ + mmio_clrbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT); + + /* Clear pending interrupts */ + for (i = 0U; i < EP_NB; i++) { + mmio_write_32(usb_base_addr + OTG_DIEP_BASE + (i * OTG_DIEP_SIZE) + OTG_DIEPINT, + OTG_DIEPINT_MASK); + mmio_write_32(usb_base_addr + OTG_DOEP_BASE + (i * OTG_DOEP_SIZE) + OTG_DOEPINT, + OTG_DOEPINT_MASK); + } + + mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK); + + /* Clear interrupt masks */ + mmio_write_32(usb_base_addr + OTG_DIEPMSK, 0U); + mmio_write_32(usb_base_addr + OTG_DOEPMSK, 0U); + mmio_write_32(usb_base_addr + OTG_DAINTMSK, 0U); + + /* Flush the FIFO */ + usb_dwc2_flush_rx_fifo(handle); + usb_dwc2_flush_tx_fifo(handle, EP_ALL); + + /* Disconnect the USB device by disabling the pull-up/pull-down */ + mmio_setbits_32((uintptr_t)handle + OTG_DCTL, OTG_DCTL_SDIS); + + return USBD_OK; +} + +/* + * Stop the USB device mode. + * handle: Selected device. + * address: New device address to be assigned. + * This parameter can be a value from 0 to 255. + * return: USB status. + */ +static enum usb_status usb_dwc2_set_address(void *handle, uint8_t address) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + mmio_clrsetbits_32(usb_base_addr + OTG_DCFG, + OTG_DCFG_DAD, + address << OTG_DCFG_DAD_SHIFT); + + return USBD_OK; +} + +/* + * Check FIFO for the next packet to be loaded. + * handle: Selected device. + * epnum : Endpoint number. + * xfer_len: Block length. + * xfer_count: Number of blocks. + * maxpacket: Max packet length. + * xfer_buff: Buffer pointer. + * return: USB status. + */ +static enum usb_status usb_dwc2_write_empty_tx_fifo(void *handle, + uint32_t epnum, + uint32_t xfer_len, + uint32_t *xfer_count, + uint32_t maxpacket, + uint8_t **xfer_buff) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t reg_offset; + int32_t len; + uint32_t len32b; + enum usb_status ret; + + len = xfer_len - *xfer_count; + + if ((len > 0) && ((uint32_t)len > maxpacket)) { + len = maxpacket; + } + + len32b = (len + 3U) / 4U; + + reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE); + + while (((mmio_read_32(reg_offset + OTG_DTXFSTS) & + OTG_DTXFSTS_INEPTFSAV) > len32b) && + (*xfer_count < xfer_len) && (xfer_len != 0U)) { + /* Write the FIFO */ + len = xfer_len - *xfer_count; + + if ((len > 0) && ((uint32_t)len > maxpacket)) { + len = maxpacket; + } + + len32b = (len + 3U) / 4U; + + ret = usb_dwc2_write_packet(handle, *xfer_buff, epnum, len); + if (ret != USBD_OK) { + return ret; + } + + *xfer_buff += len; + *xfer_count += len; + } + + if (len <= 0) { + mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum)); + } + + return USBD_OK; +} + +/* + * Handle PCD interrupt request. + * handle: PCD handle. + * param: Pointer to information updated by the IT handling. + * return: Action to do after IT handling. + */ +static enum usb_action usb_dwc2_it_handler(void *handle, uint32_t *param) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + uint32_t ep_intr; + uint32_t epint; + uint32_t epnum; + uint32_t temp; + enum usb_status ret; + + if (usb_dwc2_get_mode(handle) != USB_OTG_MODE_DEVICE) { + return USB_NOTHING; + } + + /* Avoid spurious interrupt */ + if (usb_dwc2_read_int(handle) == 0U) { + return USB_NOTHING; + } + + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_MMIS) != 0U) { + /* Incorrect mode, acknowledge the interrupt */ + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_MMIS); + } + + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OEPINT) != 0U) { + uint32_t reg_offset; + + /* Read in the device interrupt bits */ + ep_intr = usb_dwc2_all_out_ep_int(handle); + epnum = 0U; + while ((ep_intr & BIT(0)) != BIT(0)) { + epnum++; + ep_intr >>= 1; + } + + reg_offset = usb_base_addr + OTG_DOEP_BASE + (epnum * OTG_DOEP_SIZE) + OTG_DOEPINT; + + epint = usb_dwc2_out_ep_int(handle, epnum); + + if ((epint & OTG_DOEPINT_XFRC) == OTG_DOEPINT_XFRC) { + mmio_write_32(reg_offset, OTG_DOEPINT_XFRC); + *param = epnum; + + return USB_DATA_OUT; + } + + if ((epint & OTG_DOEPINT_STUP) == OTG_DOEPINT_STUP) { + /* Inform that a setup packet is available */ + mmio_write_32(reg_offset, OTG_DOEPINT_STUP); + + return USB_SETUP; + } + + if ((epint & OTG_DOEPINT_OTEPDIS) == OTG_DOEPINT_OTEPDIS) { + mmio_write_32(reg_offset, OTG_DOEPINT_OTEPDIS); + } + } + + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IEPINT) != 0U) { + uint32_t reg_offset; + + /* Read in the device interrupt bits */ + ep_intr = usb_dwc2_all_in_ep_int(handle); + epnum = 0U; + while ((ep_intr & BIT(0)) != BIT(0)) { + epnum++; + ep_intr >>= 1; + } + + reg_offset = usb_base_addr + OTG_DIEP_BASE + (epnum * OTG_DIEP_SIZE) + OTG_DIEPINT; + + epint = usb_dwc2_in_ep_int(handle, epnum); + + if ((epint & OTG_DIEPINT_XFRC) == OTG_DIEPINT_XFRC) { + mmio_clrbits_32(usb_base_addr + OTG_DIEPEMPMSK, BIT(epnum)); + mmio_write_32(reg_offset, OTG_DIEPINT_XFRC); + *param = epnum; + + return USB_DATA_IN; + } + + if ((epint & OTG_DIEPINT_TOC) == OTG_DIEPINT_TOC) { + mmio_write_32(reg_offset, OTG_DIEPINT_TOC); + } + + if ((epint & OTG_DIEPINT_ITTXFE) == OTG_DIEPINT_ITTXFE) { + mmio_write_32(reg_offset, OTG_DIEPINT_ITTXFE); + } + + if ((epint & OTG_DIEPINT_INEPNE) == OTG_DIEPINT_INEPNE) { + mmio_write_32(reg_offset, OTG_DIEPINT_INEPNE); + } + + if ((epint & OTG_DIEPINT_EPDISD) == OTG_DIEPINT_EPDISD) { + mmio_write_32(reg_offset, OTG_DIEPINT_EPDISD); + } + + if ((epint & OTG_DIEPINT_TXFE) == OTG_DIEPINT_TXFE) { + *param = epnum; + + return USB_WRITE_EMPTY; + } + } + + /* Handle resume interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_WKUPINT) != 0U) { + INFO("handle USB : Resume\n"); + + /* Clear the remote wake-up signaling */ + mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG); + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_WKUPINT); + + return USB_RESUME; + } + + /* Handle suspend interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBSUSP) != 0U) { + INFO("handle USB : Suspend int\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBSUSP); + + if ((mmio_read_32(usb_base_addr + OTG_DSTS) & + OTG_DSTS_SUSPSTS) == OTG_DSTS_SUSPSTS) { + return USB_SUSPEND; + } + } + + /* Handle LPM interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_LPMINT) != 0U) { + INFO("handle USB : LPM int enter in suspend\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_LPMINT); + *param = (mmio_read_32(usb_base_addr + OTG_GLPMCFG) & + OTG_GLPMCFG_BESL) >> 2; + + return USB_LPM; + } + + /* Handle reset interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_USBRST) != 0U) { + INFO("handle USB : Reset\n"); + + mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_RWUSIG); + + usb_dwc2_flush_tx_fifo(handle, 0U); + + mmio_write_32(usb_base_addr + OTG_DAINT, OTG_DAINT_IN_MASK | OTG_DAINT_OUT_MASK); + mmio_setbits_32(usb_base_addr + OTG_DAINTMSK, OTG_DAINT_EP0_IN | OTG_DAINT_EP0_OUT); + + mmio_setbits_32(usb_base_addr + OTG_DOEPMSK, OTG_DOEPMSK_STUPM | + OTG_DOEPMSK_XFRCM | + OTG_DOEPMSK_EPDM); + mmio_setbits_32(usb_base_addr + OTG_DIEPMSK, OTG_DIEPMSK_TOM | + OTG_DIEPMSK_XFRCM | + OTG_DIEPMSK_EPDM); + + /* Set default address to 0 */ + mmio_clrbits_32(usb_base_addr + OTG_DCFG, OTG_DCFG_DAD); + + /* Setup EP0 to receive SETUP packets */ + ret = usb_dwc2_ep0_out_start(handle); + if (ret != USBD_OK) { + return ret; + } + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_USBRST); + + return USB_RESET; + } + + /* Handle enumeration done interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_ENUMDNE) != 0U) { + ret = usb_dwc2_activate_setup(handle); + if (ret != USBD_OK) { + return ret; + } + + mmio_clrbits_32(usb_base_addr + OTG_GUSBCFG, OTG_GUSBCFG_TRDT); + + mmio_setbits_32(usb_base_addr + OTG_GUSBCFG, + (USBD_HS_TRDT_VALUE << OTG_GUSBCFG_TRDT_SHIFT) & OTG_GUSBCFG_TRDT); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_ENUMDNE); + + return USB_ENUM_DONE; + } + + /* Handle RXQLevel interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_RXFLVL) != 0U) { + mmio_clrbits_32(usb_base_addr + OTG_GINTMSK, + OTG_GINTSTS_RXFLVL); + + temp = mmio_read_32(usb_base_addr + OTG_GRXSTSP); + + *param = temp & OTG_GRXSTSP_EPNUM; + *param |= (temp & OTG_GRXSTSP_BCNT) << (USBD_OUT_COUNT_SHIFT - + OTG_GRXSTSP_BCNT_SHIFT); + + if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) == STS_DATA_UPDT) { + if ((temp & OTG_GRXSTSP_BCNT) != 0U) { + mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); + + return USB_READ_DATA_PACKET; + } + } else if (((temp & OTG_GRXSTSP_PKTSTS) >> OTG_GRXSTSP_PKTSTS_SHIFT) == + STS_SETUP_UPDT) { + mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); + + return USB_READ_SETUP_PACKET; + } + + mmio_setbits_32(usb_base_addr + OTG_GINTMSK, OTG_GINTSTS_RXFLVL); + } + + /* Handle SOF interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SOF) != 0U) { + INFO("handle USB : SOF\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SOF); + + return USB_SOF; + } + + /* Handle incomplete ISO IN interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IISOIXFR) != 0U) { + INFO("handle USB : ISO IN\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, + OTG_GINTSTS_IISOIXFR); + } + + /* Handle incomplete ISO OUT interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_IPXFR_INCOMPISOOUT) != + 0U) { + INFO("handle USB : ISO OUT\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, + OTG_GINTSTS_IPXFR_INCOMPISOOUT); + } + + /* Handle connection event interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_SRQINT) != 0U) { + INFO("handle USB : Connect\n"); + + mmio_write_32(usb_base_addr + OTG_GINTSTS, OTG_GINTSTS_SRQINT); + } + + /* Handle disconnection event interrupt */ + if ((usb_dwc2_read_int(handle) & OTG_GINTSTS_OTGINT) != 0U) { + INFO("handle USB : Disconnect\n"); + + temp = mmio_read_32(usb_base_addr + OTG_GOTGINT); + + if ((temp & OTG_GOTGINT_SEDET) == OTG_GOTGINT_SEDET) { + return USB_DISCONNECT; + } + } + + return USB_NOTHING; +} + +/* + * Start the usb device mode + * usb_core_handle: USB core driver handle. + * return USB status. + */ +static enum usb_status usb_dwc2_start_device(void *handle) +{ + uintptr_t usb_base_addr = (uintptr_t)handle; + + mmio_clrbits_32(usb_base_addr + OTG_DCTL, OTG_DCTL_SDIS); + mmio_setbits_32(usb_base_addr + OTG_GAHBCFG, OTG_GAHBCFG_GINT); + + return USBD_OK; +} + +static const struct usb_driver usb_dwc2driver = { + .ep0_out_start = usb_dwc2_ep0_out_start, + .ep_start_xfer = usb_dwc2_ep_start_xfer, + .ep0_start_xfer = usb_dwc2_ep0_start_xfer, + .write_packet = usb_dwc2_write_packet, + .read_packet = usb_dwc2_read_packet, + .ep_set_stall = usb_dwc2_ep_set_stall, + .start_device = usb_dwc2_start_device, + .stop_device = usb_dwc2_stop_device, + .set_address = usb_dwc2_set_address, + .write_empty_tx_fifo = usb_dwc2_write_empty_tx_fifo, + .it_handler = usb_dwc2_it_handler +}; + +/* + * Initialize USB DWC2 driver. + * usb_core_handle: USB core driver handle. + * pcd_handle: PCD handle. + * base_register: USB global register base address. + */ +void stm32mp1_usb_init_driver(struct usb_handle *usb_core_handle, + struct pcd_handle *pcd_handle, + void *base_register) +{ + register_usb_driver(usb_core_handle, pcd_handle, &usb_dwc2driver, + base_register); +} diff --git a/include/drivers/st/stm32mp1_usb.h b/include/drivers/st/stm32mp1_usb.h new file mode 100644 index 000000000..06a34cb27 --- /dev/null +++ b/include/drivers/st/stm32mp1_usb.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32MP1_USB_H +#define STM32MP1_USB_H + +#include + +void stm32mp1_usb_init_driver(struct usb_handle *usb_core_handle, + struct pcd_handle *pcd_handle, + void *base_register); + +#endif /* STM32MP1_USB_H */ -- cgit v1.2.3 From afad5214a79259f56bc2003b00859abfe8a18d4d Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Mon, 14 Sep 2020 11:13:34 +0200 Subject: feat(plat/st): add STM32CubeProgrammer support on USB Add a file to support over USB the STMicroelectronics tool STM32CubeProgrammer in BL2 for STM32MP15x platform. This tools is based on DFU stack. Change-Id: I48a8f772cb0e9b8be24c06847f724f0470c0f917 Signed-off-by: Patrick Delaunay --- plat/st/common/include/stm32cubeprogrammer.h | 27 ++++ plat/st/common/stm32cubeprogrammer_usb.c | 196 +++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 plat/st/common/include/stm32cubeprogrammer.h create mode 100644 plat/st/common/stm32cubeprogrammer_usb.c diff --git a/plat/st/common/include/stm32cubeprogrammer.h b/plat/st/common/include/stm32cubeprogrammer.h new file mode 100644 index 000000000..503d91945 --- /dev/null +++ b/plat/st/common/include/stm32cubeprogrammer.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STM32CUBEPROGRAMMER_H +#define STM32CUBEPROGRAMMER_H + +#include + +#include + +/* Phase definition */ +#define PHASE_FLASHLAYOUT 0U +#define PHASE_SSBL 3U +#define PHASE_CMD 0xF1U +#define PHASE_RESET 0xFFU + +/* Functions provided by plat */ +uint8_t usb_dfu_get_phase(uint8_t alt); + +int stm32cubeprog_usb_load(struct usb_handle *usb_core_handle, + uintptr_t ssbl_base, + size_t ssbl_len); + +#endif /* STM32CUBEPROGRAMMER_H */ diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c new file mode 100644 index 000000000..4cd210e9e --- /dev/null +++ b/plat/st/common/stm32cubeprogrammer_usb.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include + +#include +#include + +/* Undefined download address */ +#define UNDEFINED_DOWN_ADDR 0xFFFFFFFF + +struct dfu_state { + uint8_t phase; + uintptr_t base; + size_t len; + uintptr_t address; + /* working buffer */ + uint8_t buffer[UCHAR_MAX]; +}; + +static struct dfu_state dfu_state; + +/* minimal size of Get Pḧase = offset for additionnl information */ +#define GET_PHASE_LEN 9 + +#define DFU_ERROR(...) \ + { \ + ERROR(__VA_ARGS__); \ + if (dfu->phase != PHASE_RESET) { \ + snprintf((char *)&dfu->buffer[GET_PHASE_LEN], \ + sizeof(dfu->buffer) - GET_PHASE_LEN, \ + __VA_ARGS__); \ + dfu->phase = PHASE_RESET; \ + dfu->address = UNDEFINED_DOWN_ADDR; \ + dfu->len = 0; \ + } \ + } + +static bool is_valid_header(fip_toc_header_t *header) +{ + if ((header->name == TOC_HEADER_NAME) && (header->serial_number != 0U)) { + return true; + } + + return false; +} + +static int dfu_callback_upload(uint8_t alt, uintptr_t *buffer, uint32_t *len, + void *user_data) +{ + int result = 0; + uint32_t length = 0; + struct dfu_state *dfu = (struct dfu_state *)user_data; + + switch (usb_dfu_get_phase(alt)) { + case PHASE_CMD: + /* Get Pḧase */ + dfu->buffer[0] = dfu->phase; + dfu->buffer[1] = (uint8_t)(dfu->address); + dfu->buffer[2] = (uint8_t)(dfu->address >> 8); + dfu->buffer[3] = (uint8_t)(dfu->address >> 16); + dfu->buffer[4] = (uint8_t)(dfu->address >> 24); + dfu->buffer[5] = 0x00; + dfu->buffer[6] = 0x00; + dfu->buffer[7] = 0x00; + dfu->buffer[8] = 0x00; + length = GET_PHASE_LEN; + if (dfu->phase == PHASE_FLASHLAYOUT && + dfu->address == UNDEFINED_DOWN_ADDR) { + INFO("Send detach request\n"); + dfu->buffer[length++] = 0x01; + } + if (dfu->phase == PHASE_RESET) { + /* error information is added by DFU_ERROR macro */ + length += strnlen((char *)&dfu->buffer[GET_PHASE_LEN], + sizeof(dfu->buffer) - GET_PHASE_LEN) + - 1; + } + break; + + default: + DFU_ERROR("phase ID :%i, alternate %i for phase %i\n", + dfu->phase, alt, usb_dfu_get_phase(alt)); + result = -EIO; + break; + } + + if (result == 0) { + *len = length; + *buffer = (uintptr_t)dfu->buffer; + } + + return result; +} + +static int dfu_callback_download(uint8_t alt, uintptr_t *buffer, uint32_t *len, + void *user_data) +{ + struct dfu_state *dfu = (struct dfu_state *)user_data; + + if ((dfu->phase != usb_dfu_get_phase(alt)) || + (dfu->address == UNDEFINED_DOWN_ADDR)) { + DFU_ERROR("phase ID :%i, alternate %i, address %x\n", + dfu->phase, alt, (uint32_t)dfu->address); + return -EIO; + } + + VERBOSE("Download %d %lx %x\n", alt, dfu->address, *len); + *buffer = dfu->address; + dfu->address += *len; + + if (dfu->address - dfu->base > dfu->len) { + return -EIO; + } + + return 0; +} + +static int dfu_callback_manifestation(uint8_t alt, void *user_data) +{ + struct dfu_state *dfu = (struct dfu_state *)user_data; + + if (dfu->phase != usb_dfu_get_phase(alt)) { + ERROR("Manifestation phase ID :%i, alternate %i, address %lx\n", + dfu->phase, alt, dfu->address); + return -EIO; + } + + INFO("phase ID :%i, Manifestation %d at %lx\n", + dfu->phase, alt, dfu->address); + + switch (dfu->phase) { + case PHASE_SSBL: + if (!is_valid_header((fip_toc_header_t *)dfu->base)) { + DFU_ERROR("FIP Header check failed for phase %d\n", alt); + return -EIO; + } + VERBOSE("FIP header looks OK.\n"); + + /* Configure End with request detach */ + dfu->phase = PHASE_FLASHLAYOUT; + dfu->address = UNDEFINED_DOWN_ADDR; + dfu->len = 0; + break; + default: + DFU_ERROR("Unknown phase\n"); + } + + return 0; +} + +/* Open a connection to the USB device */ +static const struct usb_dfu_media usb_dfu_fops = { + .upload = dfu_callback_upload, + .download = dfu_callback_download, + .manifestation = dfu_callback_manifestation, +}; + +int stm32cubeprog_usb_load(struct usb_handle *usb_core_handle, + uintptr_t base, + size_t len) +{ + int ret; + + usb_core_handle->user_data = (void *)&dfu_state; + + INFO("DFU USB START...\n"); + ret = usb_core_start(usb_core_handle); + if (ret != USBD_OK) { + return -EIO; + } + + dfu_state.phase = PHASE_SSBL; + dfu_state.address = base; + dfu_state.base = base; + dfu_state.len = len; + + ret = usb_dfu_loop(usb_core_handle, &usb_dfu_fops); + if (ret != USBD_OK) { + return -EIO; + } + + INFO("DFU USB STOP...\n"); + ret = usb_core_stop(usb_core_handle); + if (ret != USBD_OK) { + return -EIO; + } + + return 0; +} -- cgit v1.2.3 From 942f6be211d4816ad2568d30d807b8fd53d7f981 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 30 Jun 2021 17:06:19 +0200 Subject: feat(plat/st/stm32mp1): add USB DFU support for STM32MP1 Add the USB descriptor, the struct used for USB enumeration with the function usb_dfu_plat_init(). The USB support is based on the usb lib and on the stm32mp1 usb driver. The content of enumeration (the string descriptor) is identical to ROM code to avoid the USB reset en re-enumeration needs. Signed-off-by: Patrick Delaunay Change-Id: I18b40649e8df83813a5a340b0eee44c9a3470e43 --- plat/st/stm32mp1/stm32mp1_def.h | 11 + plat/st/stm32mp1/stm32mp1_usb_dfu.c | 388 ++++++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) create mode 100644 plat/st/stm32mp1/stm32mp1_usb_dfu.c diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 469c2d93b..f5d4b2f38 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -339,6 +339,9 @@ enum ddr_type { #define DATA0_OTP U(0) #define PART_NUMBER_OTP U(1) #define NAND_OTP U(9) +#define UID0_OTP U(13) +#define UID1_OTP U(14) +#define UID2_OTP U(15) #define PACKAGE_OTP U(16) #define HW2_OTP U(18) @@ -401,6 +404,9 @@ enum ddr_type { /* NAND number of planes */ #define NAND_PLANE_BIT_NB_MASK BIT(14) +/* UID OTP */ +#define UID_WORD_NB U(3) + /******************************************************************************* * STM32MP1 TAMP ******************************************************************************/ @@ -414,6 +420,11 @@ static inline uint32_t tamp_bkpr(uint32_t idx) } #endif +/******************************************************************************* + * STM32MP1 USB + ******************************************************************************/ +#define USB_OTG_BASE U(0x49000000) + /******************************************************************************* * STM32MP1 DDRCTRL ******************************************************************************/ diff --git a/plat/st/stm32mp1/stm32mp1_usb_dfu.c b/plat/st/stm32mp1/stm32mp1_usb_dfu.c new file mode 100644 index 000000000..051d43532 --- /dev/null +++ b/plat/st/stm32mp1/stm32mp1_usb_dfu.c @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2021, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* String size (1 byte) + type (1 byte) + 24 UTF16 characters: 2 bytes each */ +#define SIZ_STRING_SERIAL U(24) +#define USB_SIZ_STRING_SERIAL (1U + 1U + (SIZ_STRING_SERIAL * 2U)) +#define USBD_MAX_STR_DESC_SIZ 0x100 +#define USBD_VID 0x0483 +#define USBD_PID 0xDF11 +#define USBD_LANGID_STRING 0x409 +#define USBD_MANUFACTURER_STRING "STMicroelectronics" +#define USBD_CONFIGURATION_STRING "DFU Config" +#define USBD_INTERFACE_STRING "DFU Interface" + +#define USB_DFU_ITF_NUM 6 + +#define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM) + +/* DFU devices */ +static struct usb_dfu_handle usb_dfu_handle; + +/* USB Standard Device Descriptor */ +static const uint8_t usb_stm32mp1_desc[USB_LEN_DEV_DESC] = { + USB_LEN_DEV_DESC, /* bLength */ + USB_DESC_TYPE_DEVICE, /* bDescriptorType */ + 0x00, /* bcdUSB */ + 0x02, /* version */ + 0x00, /* bDeviceClass */ + 0x00, /* bDeviceSubClass */ + 0x00, /* bDeviceProtocol */ + USB_MAX_EP0_SIZE, /* bMaxPacketSize */ + LOBYTE(USBD_VID), /* idVendor */ + HIBYTE(USBD_VID), /* idVendor */ + LOBYTE(USBD_PID), /* idVendor */ + HIBYTE(USBD_PID), /* idVendor */ + 0x00, /* bcdDevice rel. 2.00 */ + 0x02, + USBD_IDX_MFC_STR, /* Index of manufacturer string */ + USBD_IDX_PRODUCT_STR, /* Index of product string */ + USBD_IDX_SERIAL_STR, /* Index of serial number string */ + USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ +}; /* USB_DeviceDescriptor */ + +/* USB Standard String Descriptor */ +static const uint8_t usb_stm32mp1_lang_id_desc[USB_LEN_LANGID_STR_DESC] = { + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING), +}; + +/* USB Standard Device Descriptor */ +static const uint8_t +usbd_stm32mp1_qualifier_desc[USB_LEN_DEV_QUALIFIER_DESC] = { + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/* USB serial number: build dynamically */ +static uint8_t usb_stm32mp1_serial[USB_SIZ_STRING_SERIAL + 1]; + +/* USB DFU device Configuration Descriptor */ +static const uint8_t usb_stm32mp1_config_desc[USB_DFU_CONFIG_DESC_SIZ] = { + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x02, /* iConfiguration: Index of string descriptor for configuration */ + 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ + 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + + /* Descriptor of DFU interface 0 Alternate setting 0..N */ + USBD_DFU_IF_DESC(0), + USBD_DFU_IF_DESC(1), + USBD_DFU_IF_DESC(2), + USBD_DFU_IF_DESC(3), + USBD_DFU_IF_DESC(4), + USBD_DFU_IF_DESC(5), + + /* DFU Functional Descriptor */ + 0x09, /* blength = 9 Bytes */ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */ + DFU_BM_ATTRIBUTE, /* bmAttribute for DFU */ + 0xFF, /* DetachTimeOut = 255 ms */ + 0x00, + TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */ + ((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */ + ((USB_DFU_VERSION >> 8) & 0xFF) +}; + +/* The user strings: one by alternate as defined in USBD_DFU_IF_DESC */ +const char *const if_desc_string[USB_DFU_ITF_NUM] = { + "@Partition0 /0x00/1*256Ke", + "@FSBL /0x01/1*1Me", + "@Partition2 /0x02/1*1Me", + "@Partition3 /0x03/1*16Me", + "@Partition4 /0x04/1*16Me", + "@virtual /0xF1/1*512Ba" +}; + +/* Buffer to build the unicode string provided to USB device stack */ +static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ]; + +/* + * Convert Ascii string into unicode one + * desc : descriptor buffer + * unicode : Formatted string buffer (unicode) + * len : descriptor length + */ +static void stm32mp1_get_string(const char *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0U; + + if (desc == NULL) { + return; + } + + *len = strlen(desc) * 2U + 2U; + unicode[idx++] = *len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != '\0') { + unicode[idx++] = *desc++; + unicode[idx++] = 0x00U; + } +} + +/* + * Create the serial number string descriptor + */ +static void update_serial_num_string(void) +{ + uint8_t i; + uint32_t result; + char serial_string[SIZ_STRING_SERIAL + 2U]; + uint32_t deviceserial[UID_WORD_NB]; + uint16_t length; + + for (i = 0U; i < UID_WORD_NB; i++) { + result = bsec_shadow_register(i + UID0_OTP); + if (result != BSEC_OK) { + ERROR("BSEC: UID%d Shadowing Error\n", i); + break; + } + result = bsec_read_otp(&deviceserial[i], i + UID0_OTP); + if (result != BSEC_OK) { + ERROR("BSEC: UID%d Read Error\n", i); + break; + } + } + /* On bsec error: serial number is set to 0 */ + if (result != BSEC_OK) { + for (i = 0; i < UID_WORD_NB; i++) { + deviceserial[i] = 0U; + } + } + /* build serial number with OTP value as in ROM code */ + snprintf(serial_string, sizeof(serial_string), "%08X%08X%08X", + deviceserial[0], deviceserial[1], deviceserial[2]); + + length = USB_SIZ_STRING_SERIAL; + stm32mp1_get_string(serial_string, usb_stm32mp1_serial, &length); +} + +/* + * Return Device Qualifier descriptor + * length : pointer data length + * return : pointer to descriptor buffer + */ +static uint8_t *stm32mp1_get_qualifier_desc(uint16_t *length) +{ + *length = sizeof(usbd_stm32mp1_qualifier_desc); + + return (uint8_t *)usbd_stm32mp1_qualifier_desc; +} + +/* + * Return configuration descriptor + * length : pointer data length + * return : pointer to descriptor buffer + */ +static uint8_t *stm32mp1_get_config_desc(uint16_t *length) +{ + *length = sizeof(usb_stm32mp1_config_desc); + + return (uint8_t *)usb_stm32mp1_config_desc; +} + +/* + * Returns the device descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_device_desc(uint16_t *length) +{ + *length = sizeof(usb_stm32mp1_desc); + + return (uint8_t *)usb_stm32mp1_desc; +} + +/* + * Returns the LangID string descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_lang_id_desc(uint16_t *length) +{ + *length = sizeof(usb_stm32mp1_lang_id_desc); + + return (uint8_t *)usb_stm32mp1_lang_id_desc; +} + +/* + * Returns the product string descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_product_desc(uint16_t *length) +{ + char name[STM32_SOC_NAME_SIZE]; + char product[128]; + uint32_t chip_id; + uint32_t chip_version; + + stm32mp_get_soc_name(name); + chip_id = stm32mp_get_chip_dev_id(); + chip_version = stm32mp_get_chip_version(); + + snprintf(product, sizeof(product), + "DFU @Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,", + chip_id, chip_version, name); + + stm32mp1_get_string(product, usb_str_dec, length); + + return usb_str_dec; +} + +/* + * Returns the manufacturer string descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_manufacturer_desc(uint16_t *length) +{ + stm32mp1_get_string(USBD_MANUFACTURER_STRING, usb_str_dec, length); + + return usb_str_dec; +} + +/* + * Returns the serial number string descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_serial_desc(uint16_t *length) +{ + *length = USB_SIZ_STRING_SERIAL; + + return (uint8_t *)usb_stm32mp1_serial; +} + +/* + * Returns the configuration string descriptor. + * length: Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_config_desc(uint16_t *length) +{ + stm32mp1_get_string(USBD_CONFIGURATION_STRING, usb_str_dec, length); + + return usb_str_dec; +} + +/* + * Returns the interface string descriptor. + * length : Pointer to data length variable + * return : Pointer to descriptor buffer + */ +static uint8_t *stm32mp1_interface_desc(uint16_t *length) +{ + stm32mp1_get_string(USBD_INTERFACE_STRING, usb_str_dec, length); + + return usb_str_dec; +} + +/* + * Manages the transfer of memory interfaces string descriptors. + * index: descriptor index + * length : pointer data length + * return : pointer to the descriptor table or NULL if the descriptor + * is not supported. + */ +static uint8_t *stm32mp1_get_usr_desc(uint8_t index, uint16_t *length) +{ + if (index >= ARRAY_SIZE(if_desc_string)) { + return NULL; + } + + stm32mp1_get_string(if_desc_string[index], usb_str_dec, length); + + return usb_str_dec; +} + +static const struct usb_desc dfu_desc = { + .get_device_desc = stm32mp1_device_desc, + .get_lang_id_desc = stm32mp1_lang_id_desc, + .get_manufacturer_desc = stm32mp1_manufacturer_desc, + .get_product_desc = stm32mp1_product_desc, + .get_configuration_desc = stm32mp1_config_desc, + .get_serial_desc = stm32mp1_serial_desc, + .get_interface_desc = stm32mp1_interface_desc, + .get_usr_desc = stm32mp1_get_usr_desc, + .get_config_desc = stm32mp1_get_config_desc, + .get_device_qualifier_desc = stm32mp1_get_qualifier_desc, +}; + +static struct usb_handle usb_core_handle; +static struct pcd_handle pcd_handle; + +struct usb_handle *usb_dfu_plat_init(void) +{ + /* Prepare USB Driver */ + pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE; + pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE; + stm32mp1_usb_init_driver(&usb_core_handle, &pcd_handle, + (uint32_t *)USB_OTG_BASE); + + /* STM32MP15 = keep the configuration from ROM code */ + usb_core_handle.ep0_state = USBD_EP0_DATA_IN; + usb_core_handle.dev_state = USBD_STATE_CONFIGURED; + + /* Update the serial number string descriptor from the unique ID */ + update_serial_num_string(); + + /* Prepare USB DFU stack */ + usb_dfu_register(&usb_core_handle, &usb_dfu_handle); + + /* Register DFU descriptor in USB stack */ + register_platform(&usb_core_handle, &dfu_desc); + + return &usb_core_handle; +} + +/* Link between USB alternate and STM32CubeProgramer phase */ +uint8_t usb_dfu_get_phase(uint8_t alt) +{ + uint8_t ret; + + switch (alt) { + case 3: + ret = PHASE_SSBL; + break; + case 5: + ret = PHASE_CMD; + break; + default: + ret = PHASE_RESET; + break; + } + + return ret; +} -- cgit v1.2.3 From fa92fef0a024cdb537fe56c84a0156cc48c1ac2d Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Jul 2021 14:07:56 +0200 Subject: feat(plat/st/stm32mp1): add STM32MP_USB_PROGRAMMER target Add a support of USB as serial boot devices for STM32MP15x platform: the FIP file is provide by STM32CubeProgrammer with the DFU protocol, loaded in DDR at DWL_BUFFER_BASE address and then the io memmap is used. Signed-off-by: Patrick Delaunay Change-Id: I272c17c458ff1e9d0780f8fa22330c8a35533d19 --- plat/st/common/bl2_io_storage.c | 54 +++++++++++++++++++++++++++++++++ plat/st/stm32mp1/bl2_plat_setup.c | 14 +++++++++ plat/st/stm32mp1/include/boot_api.h | 5 ++- plat/st/stm32mp1/include/platform_def.h | 4 +++ plat/st/stm32mp1/platform.mk | 19 +++++++++++- 5 files changed, 94 insertions(+), 2 deletions(-) diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index 7e76083b3..b0314d2ab 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +33,9 @@ #include #include +#include #include +#include /* IO devices */ uintptr_t fip_dev_handle; @@ -95,6 +99,10 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = { static const io_dev_connector_t *spi_dev_con; #endif +#if STM32MP_USB_PROGRAMMER +static const io_dev_connector_t *memmap_dev_con; +#endif + io_block_spec_t image_block_spec = { .offset = 0U, .length = 0U, @@ -128,6 +136,9 @@ static void print_boot_device(boot_api_context_t *boot_context) case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: INFO("Using SPI NAND\n"); break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + INFO("Using USB\n"); + break; default: ERROR("Boot interface %u not found\n", boot_context->boot_interface_selected); @@ -246,6 +257,32 @@ static void boot_spi_nand(boot_api_context_t *boot_context) } #endif /* STM32MP_SPI_NAND */ +#if STM32MP_USB_PROGRAMMER +static void mmap_io_setup(void) +{ + int io_result __unused; + + io_result = register_io_dev_memmap(&memmap_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, + &storage_dev_handle); + assert(io_result == 0); +} + +static void stm32cubeprogrammer_usb(void) +{ + int ret __unused; + struct usb_handle *pdev; + + /* Init USB on platform */ + pdev = usb_dfu_plat_init(); + + ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + assert(ret == 0); +} +#endif + void stm32mp_io_setup(void) { int io_result __unused; @@ -297,6 +334,12 @@ void stm32mp_io_setup(void) boot_spi_nand(boot_context); break; #endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + dmbsy(); + mmap_io_setup(); + break; +#endif default: ERROR("Boot interface %d not supported\n", @@ -357,6 +400,17 @@ int bl2_plat_handle_pre_image_load(unsigned int image_id) break; #endif +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + if (image_id == FW_CONFIG_ID) { + stm32cubeprogrammer_usb(); + /* FIP loaded at DWL address */ + image_block_spec.offset = DWL_BUFFER_BASE; + image_block_spec.length = DWL_BUFFER_SIZE; + } + break; +#endif + default: ERROR("FIP Not found\n"); panic(); diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index e87c529b7..7eaf0ed98 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -490,5 +490,19 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) void bl2_el3_plat_prepare_exit(void) { + uint16_t boot_itf = stm32mp_get_boot_itf_selected(); + + switch (boot_itf) { +#if STM32MP_USB_PROGRAMMER + case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: + /* Invalidate the downloaded buffer used with io_memmap */ + inv_dcache_range(DWL_BUFFER_BASE, DWL_BUFFER_SIZE); + break; +#endif + default: + /* Do nothing in default case */ + break; + } + stm32mp1_security_setup(); } diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h index c16639ac4..52b1d1aa0 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,6 +39,9 @@ /* Boot occurred on QSPI NOR */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U +/* Boot occurred on USB */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB 0x6U + /* Boot occurred on QSPI NAND */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h index 8a065bf75..1e9443ece 100644 --- a/plat/st/stm32mp1/include/platform_def.h +++ b/plat/st/stm32mp1/include/platform_def.h @@ -92,6 +92,10 @@ */ #define PLAT_STM32MP_NS_IMAGE_OFFSET BL33_BASE +/* Needed by STM32CubeProgrammer support */ +#define DWL_BUFFER_BASE (STM32MP_DDR_BASE + U(0x08000000)) +#define DWL_BUFFER_SIZE U(0x08000000) + /* * SSBL offset in case it's stored in eMMC boot partition. * We can fix it to 256K because TF-A size can't be bigger than SRAM diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 14f90d466..c8c2e5f0b 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -53,6 +53,9 @@ STM32MP_SPI_NAND ?= 0 STM32MP_SPI_NOR ?= 0 STM32MP_EMMC_BOOT ?= 0 +# Serial boot devices +STM32MP_USB_PROGRAMMER ?= 0 + # Device tree DTB_FILE_NAME ?= stm32mp157c-ev1.dtb ifeq ($(STM32MP_USE_STM32IMAGE),1) @@ -127,6 +130,7 @@ $(eval $(call assert_booleans,\ STM32MP_SPI_NOR \ STM32MP_EMMC_BOOT \ PLAT_XLAT_TABLES_DYNAMIC \ + STM32MP_USB_PROGRAMMER \ STM32MP_USE_STM32IMAGE \ ))) @@ -147,6 +151,7 @@ $(eval $(call add_defines,\ PLAT_XLAT_TABLES_DYNAMIC \ STM32_TF_A_COPIES \ PLAT_PARTITION_MAX_ENTRIES \ + STM32MP_USB_PROGRAMMER \ STM32MP_USE_STM32IMAGE \ ))) @@ -251,6 +256,17 @@ ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c endif +ifeq (${STM32MP_USB_PROGRAMMER},1) +#The DFU stack uses only one end point, reduce the USB stack footprint +$(eval $(call add_define_val,CONFIG_USBD_EP_NB,1U)) +BL2_SOURCES += drivers/io/io_memmap.c \ + drivers/st/usb/stm32mp1_usb.c \ + drivers/usb/usb_device.c \ + plat/st/common/stm32cubeprogrammer_usb.c \ + plat/st/common/usb_dfu.c \ + plat/st/stm32mp1/stm32mp1_usb_dfu.c +endif + BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ drivers/st/ddr/stm32mp1_ram.c @@ -274,7 +290,8 @@ check_boot_device: [ ${STM32MP_SDMMC} != 1 ] && \ [ ${STM32MP_RAW_NAND} != 1 ] && \ [ ${STM32MP_SPI_NAND} != 1 ] && \ - [ ${STM32MP_SPI_NOR} != 1 ]; then \ + [ ${STM32MP_SPI_NOR} != 1 ] && \ + [ ${STM32MP_USB_PROGRAMMER} != 1 ]; then \ echo "No boot device driver is enabled"; \ false; \ fi -- cgit v1.2.3 From 2062a3936f209c31ace73705754a3442305a577d Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Mon, 1 Nov 2021 11:11:45 +0000 Subject: fix(amu): remove `amu_fconf.c` This file is unused and was introduced accidentally by one of the commits in the MPMM patch stack. This functionality was instead introduced by `fconf_amu_getter.c`. Change-Id: Ib15b1114bacf9a2e7414c1fb35bd4fbdf0179210 Signed-off-by: Chris Kay --- lib/extensions/amu/amu_fconf.c | 200 ----------------------------------------- 1 file changed, 200 deletions(-) delete mode 100644 lib/extensions/amu/amu_fconf.c diff --git a/lib/extensions/amu/amu_fconf.c b/lib/extensions/amu/amu_fconf.c deleted file mode 100644 index c7fb80362..000000000 --- a/lib/extensions/amu/amu_fconf.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2021, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include "amu_private.h" -#include -#include -#include -#include -#include - -#include - -static bool amu_topology_populated_ ; /* Whether the topology is valid */ -static struct amu_fconf_topology amu_topology_; /* Populated topology cache */ - -const struct amu_fconf_topology *amu_topology(void) -{ - if (!amu_topology_populated_) { - return NULL; - } - - return &amu_topology_; -} - -/* - * Populate the core-specific AMU structure with information retrieved from a - * device tree. - * - * Returns `0` on success, or a negative integer representing an error code. - */ -static int amu_fconf_populate_cpu_amu(const void *fdt, int parent, - struct amu_fconf_core *amu) -{ - int ret = 0; - int node = 0; - - fdt_for_each_subnode(node, fdt, parent) { - const char *name; - const char *value; - int len; - - uintptr_t idx = 0U; - - name = fdt_get_name(fdt, node, &len); - if (strncmp(name, "counter@", 8) != 0) { - continue; - } - - ret = fdt_get_reg_props_by_index(fdt, node, 0, &idx, NULL); - if (ret < 0) { - break; - } - - value = fdt_getprop(fdt, node, "enable-at-el3", &len); - if ((value == NULL) && (len != -FDT_ERR_NOTFOUND)) { - break; - } - - if (len != -FDT_ERR_NOTFOUND) { - amu->enable |= (1 << idx); - } - } - - if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { - return node; - } - - return ret; -} - -/* - * Within a `cpu` node, attempt to dereference the `amu` property, and populate - * the AMU information for the core. - * - * Returns `0` on success, or a negative integer representing an error code. - */ -static int amu_fconf_populate_cpu(const void *fdt, int node, uintptr_t mpidr) -{ - int ret; - int idx; - - uint32_t amu_phandle; - struct amu_fconf_core *amu; - - ret = fdt_read_uint32(fdt, node, "amu", &amu_phandle); - if (ret < 0) { - if (ret == -FDT_ERR_NOTFOUND) { - ret = 0; - } - - return ret; - } - - node = fdt_node_offset_by_phandle(fdt, amu_phandle); - if (node < 0) { - return node; - } - - idx = plat_core_pos_by_mpidr(mpidr); - amu = &amu_topology_.cores[idx]; - - return amu_fconf_populate_cpu_amu(fdt, node, amu); -} - -/* - * For every CPU node (`/cpus/cpu@n`) in an FDT, executes a callback passing a - * pointer to the FDT and the offset of the CPU node. If the return value of the - * callback is negative, it is treated as an error and the loop is aborted. In - * this situation, the value of the callback is returned from the function. - * - * Returns `0` on success, or a negative integer representing an error code. - */ -static int amu_fconf_foreach_cpu(const void *fdt, - int (*callback)(const void *, int, uintptr_t)) -{ - int ret = 0; - int parent, node = 0; - - parent = fdt_path_offset(fdt, "/cpus"); - if (parent < 0) { - if (parent == -FDT_ERR_NOTFOUND) { - parent = 0; - } - - return parent; - } - - fdt_for_each_subnode(node, fdt, parent) { - const char *name; - int len; - - uintptr_t mpidr = 0U; - - name = fdt_get_name(fdt, node, &len); - if (strncmp(name, "cpu@", 4) != 0) { - continue; - } - - ret = fdt_get_reg_props_by_index(fdt, node, 0, &mpidr, NULL); - if (ret < 0) { - break; - } - - ret = callback(fdt, node, mpidr); - if (ret < 0) { - break; - } - } - - if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { - return node; - } - - return ret; -} - -/* - * Populates the global `amu_topology` structure based on what's described by - * the hardware configuration device tree blob. - * - * The device tree is expected to provide an `amu` property for each `cpu` node, - * like so: - * - * cpu@0 { - * amu = <&cpu0_amu>; - * }; - * - * amus { - * cpu0_amu: amu-0 { - * counters { - * #address-cells = <2>; - * #size-cells = <0>; - * - * counter@x,y { - * reg = ; // Group x, counter y - * }; - * }; - * }; - * }; - */ -static int amu_fconf_populate(uintptr_t config) -{ - int ret = amu_fconf_foreach_cpu( - (const void *)config, amu_fconf_populate_cpu); - if (ret < 0) { - ERROR("AMU-FCONF: Failed to configure AMU: %d\n", ret); - } else { - amu_topology_populated_ = true; - } - - return ret; -} - -FCONF_REGISTER_POPULATOR(HW_CONFIG, amu, amu_fconf_populate); -- cgit v1.2.3 From 77a0a7f1d96b188849d1d8d8884b3c93857d3f69 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 2 Nov 2021 18:03:31 +0100 Subject: fix(checkpatch): do not check merge commits Add the --no-merges option when listing patches to check with rev-list command, when running make checkpatch. Change-Id: I47f3f5dfe358ed2b960a754f70aec0dc3c2b4536 Signed-off-by: Yann Gautier --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e5ab3247e..2a1d4d8ef 100644 --- a/Makefile +++ b/Makefile @@ -1318,7 +1318,8 @@ checkpatch: locate-checkpatch echo " with ${CHECKPATCH_OPTS} option(s)"; \ fi ${Q}COMMON_COMMIT=$$(git merge-base HEAD ${BASE_COMMIT}); \ - for commit in `git rev-list $$COMMON_COMMIT..HEAD`; do \ + for commit in `git rev-list --no-merges $$COMMON_COMMIT..HEAD`; \ + do \ printf "\n[*] Checking style of '$$commit'\n\n"; \ git log --format=email "$$commit~..$$commit" \ -- ${CHECK_PATHS} | \ -- cgit v1.2.3 From 306dcd6b0d1981b75e103c560a4034bdaa6862d5 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 2 Nov 2021 17:03:46 +0100 Subject: fix(plat/st): remove double space Replace double space with single space in stm32cubeprogrammer_usb.c. Change-Id: I717b136119e85fe8e25dd540758525f995200458 Signed-off-by: Yann Gautier --- plat/st/common/stm32cubeprogrammer_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plat/st/common/stm32cubeprogrammer_usb.c b/plat/st/common/stm32cubeprogrammer_usb.c index 4cd210e9e..19a6bbae8 100644 --- a/plat/st/common/stm32cubeprogrammer_usb.c +++ b/plat/st/common/stm32cubeprogrammer_usb.c @@ -116,7 +116,7 @@ static int dfu_callback_download(uint8_t alt, uintptr_t *buffer, uint32_t *len, dfu->address += *len; if (dfu->address - dfu->base > dfu->len) { - return -EIO; + return -EIO; } return 0; -- cgit v1.2.3 From a19bd32ed14c33571f3715198d47bac9d0f2808e Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 28 Sep 2021 15:35:39 +0200 Subject: feat(tc0): add Ivy partition Signed-off-by: Olivier Deprez Signed-off-by: Madhukar Pappireddy Change-Id: Ie9d6a77722b2350c8479ecf7b0df701428e4da73 --- plat/arm/board/tc/fdts/tc_spmc_manifest.dts | 7 +++++++ plat/arm/board/tc/fdts/tc_tb_fw_config.dts | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts index a8592f6bf..d3a5e1a77 100644 --- a/plat/arm/board/tc/fdts/tc_spmc_manifest.dts +++ b/plat/arm/board/tc/fdts/tc_spmc_manifest.dts @@ -43,6 +43,13 @@ vcpu_count = <1>; mem_size = <1048576>; }; + vm4 { + is_ffa_partition; + debug_name = "ivy"; + load_address = <0xfe600000>; + vcpu_count = <1>; + mem_size = <1048576>; + }; }; cpus { diff --git a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts index af80550db..4c6ccef25 100644 --- a/plat/arm/board/tc/fdts/tc_tb_fw_config.dts +++ b/plat/arm/board/tc/fdts/tc_tb_fw_config.dts @@ -64,6 +64,12 @@ uuid = "79b55c73-1d8c-44b9-8593-61e1770ad8d2"; load-address = <0xfe200000>; }; + + ivy { + uuid = "eaba83d8-baaf-4eaf-8144-f7fdcbe544a7"; + load-address = <0xfe600000>; + owner = "Plat"; + }; #endif #endif /* ARM_BL2_SP_LIST_DTS */ }; -- cgit v1.2.3 From 8cb99c3fc3539bb9926e73a1c33fd72f424fc453 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Wed, 5 Aug 2020 11:27:42 +0200 Subject: feat(SPMD): route secure interrupts to SPMC Define a handler in the SPMD to route secure interrupts occurring while the normal world runs. On a Group1 Secure interrupt (with a GICv3 or a Group0 interrupt on GICv2), the normal world is pre-empted to EL3 and redirected to the SPMD/SPMC for further handling. Signed-off-by: Olivier Deprez Signed-off-by: Madhukar Pappireddy Change-Id: I1350d74048c5549a2af8da0ba004c08512cc006a --- include/services/ffa_svc.h | 1 + services/std_svc/spmd/spmd_main.c | 84 ++++++++++++++++++++++++++++++++++-- services/std_svc/spmd/spmd_private.h | 1 + 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h index 85ff703bc..4c049c5f8 100644 --- a/include/services/ffa_svc.h +++ b/include/services/ffa_svc.h @@ -139,6 +139,7 @@ #define FFA_NOTIFICATION_INFO_GET \ FFA_FID(SMC_32, FFA_FNUM_NOTIFICATION_INFO_GET) #define FFA_SPM_ID_GET FFA_FID(SMC_32, FFA_FNUM_SPM_ID_GET) +#define FFA_NORMAL_WORLD_RESUME FFA_FID(SMC_32, FFA_FNUM_NORMAL_WORLD_RESUME) /* FFA SMC64 FIDs */ #define FFA_ERROR_SMC64 FFA_FID(SMC_64, FFA_FNUM_ERROR) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6de5feb0e..109a1bcbe 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -167,6 +168,62 @@ static int32_t spmd_init(void) return 1; } +/******************************************************************************* + * spmd_secure_interrupt_handler + * Enter the SPMC for further handling of the secure interrupt by the SPMC + * itself or a Secure Partition. + ******************************************************************************/ +static uint64_t spmd_secure_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + spmd_spm_core_context_t *ctx = spmd_get_context(); + gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx); + unsigned int linear_id = plat_my_core_pos(); + int64_t rc; + + /* Sanity check the security state when the exception was generated */ + assert(get_interrupt_src_ss(flags) == NON_SECURE); + + /* Sanity check the pointer to this cpu's context */ + assert(handle == cm_get_context(NON_SECURE)); + + /* Save the non-secure context before entering SPMC */ + cm_el1_sysregs_context_save(NON_SECURE); +#if SPMD_SPM_AT_SEL2 + cm_el2_sysregs_context_save(NON_SECURE); +#endif + + /* Convey the event to the SPMC through the FFA_INTERRUPT interface. */ + write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_INTERRUPT); + write_ctx_reg(gpregs, CTX_GPREG_X1, 0); + write_ctx_reg(gpregs, CTX_GPREG_X2, 0); + write_ctx_reg(gpregs, CTX_GPREG_X3, 0); + write_ctx_reg(gpregs, CTX_GPREG_X4, 0); + write_ctx_reg(gpregs, CTX_GPREG_X5, 0); + write_ctx_reg(gpregs, CTX_GPREG_X6, 0); + write_ctx_reg(gpregs, CTX_GPREG_X7, 0); + + /* Mark current core as handling a secure interrupt. */ + ctx->secure_interrupt_ongoing = true; + + rc = spmd_spm_core_sync_entry(ctx); + if (rc != 0ULL) { + ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id); + } + + ctx->secure_interrupt_ongoing = false; + + cm_el1_sysregs_context_restore(NON_SECURE); +#if SPMD_SPM_AT_SEL2 + cm_el2_sysregs_context_restore(NON_SECURE); +#endif + cm_set_next_eret_context(NON_SECURE); + + SMC_RET0(&ctx->cpu_ctx); +} + /******************************************************************************* * Loads SPMC manifest and inits SPMC. ******************************************************************************/ @@ -174,7 +231,7 @@ static int spmd_spmc_init(void *pm_addr) { cpu_context_t *cpu_ctx; unsigned int core_id; - uint32_t ep_attr; + uint32_t ep_attr, flags; int rc; /* Load the SPM Core manifest */ @@ -290,6 +347,19 @@ static int spmd_spmc_init(void *pm_addr) INFO("SPM Core setup done.\n"); + /* + * Register an interrupt handler routing secure interrupts to SPMD + * while the NWd is running. + */ + flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, + spmd_secure_interrupt_handler, + flags); + if (rc != 0) { + panic(); + } + return 0; } @@ -603,7 +673,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, case FFA_MSG_SEND_DIRECT_RESP_SMC32: if (secure_origin && spmd_is_spmc_message(x1)) { - spmd_spm_core_sync_exit(0); + spmd_spm_core_sync_exit(0ULL); } else { /* Forward direct message to the other world */ return spmd_smc_forward(smc_fid, secure_origin, @@ -675,7 +745,7 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, * SPM Core initialised successfully. */ if (secure_origin && (ctx->state == SPMC_STATE_ON_PENDING)) { - spmd_spm_core_sync_exit(0); + spmd_spm_core_sync_exit(0ULL); } /* Fall through to forward the call to the other world */ @@ -691,6 +761,14 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, x1, x2, x3, x4, handle); break; /* not reached */ + case FFA_NORMAL_WORLD_RESUME: + if (secure_origin && ctx->secure_interrupt_ongoing) { + spmd_spm_core_sync_exit(0ULL); + } else { + return spmd_ffa_error_return(handle, FFA_ERROR_DENIED); + } + break; /* Not reached */ + default: WARN("SPM: Unsupported call 0x%08x\n", smc_fid); return spmd_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED); diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 6d51a58e0..1fe506524 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -50,6 +50,7 @@ typedef struct spmd_spm_core_context { uint64_t c_rt_ctx; cpu_context_t cpu_ctx; spmc_state_t state; + bool secure_interrupt_ongoing; } spmd_spm_core_context_t; /* -- cgit v1.2.3 From 0cb9870ddfa1b2fec50debe6d6333cbcb3df1e7e Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 2 Nov 2021 11:09:12 +0100 Subject: fix(drivers/usb): fix Null pointer dereferences in usb_core_set_config Correct the invalid test on NULL pointer pdev->class in usb_core_set_config function. This patch fix the coverity errors: ** CID 373790: Null pointer dereferences (FORWARD_NULL) /drivers/usb/usb_device.c: 182 in usb_core_set_config() Signed-off-by: Patrick Delaunay Change-Id: I83e43261bafa2d47f800e56df0b047a6c58a1e29 --- drivers/usb/usb_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c index ce02d4fc4..27b78e7da 100644 --- a/drivers/usb/usb_device.c +++ b/drivers/usb/usb_device.c @@ -174,7 +174,7 @@ static void usb_core_set_config(struct usb_handle *pdev, struct usb_setup_req *r pdev->dev_config = cfgidx; pdev->class->de_init(pdev, cfgidx); } else if (cfgidx != pdev->dev_config) { - if (pdev->class != NULL) { + if (pdev->class == NULL) { usb_core_ctl_error(pdev); return; } -- cgit v1.2.3 From 7ca49284be083b03ae11aa348b40358876ee5d4b Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 2 Nov 2021 13:14:45 +0100 Subject: fix(drivers/usb): remove deadcode when USBD_EP_NB = 1 CID 373791: Control flow issues (DEADCODE) CID 373789: Control flow issues (DEADCODE) Since USBD_EP_NB = 1 for DFU stack on STMP32MP15 platform (only EP0 is required for DFU support) the value of num can't be different of 0 and the code can't be reached in usb_core_receive / usb_core_transmit. Add a simple sub-function with this part of code. Signed-off-by: Patrick Delaunay Change-Id: I07a56909bb1e6de19ce52da7945b6d2916be8538 --- drivers/usb/usb_device.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c index 27b78e7da..8f73a6bb0 100644 --- a/drivers/usb/usb_device.c +++ b/drivers/usb/usb_device.c @@ -611,6 +611,17 @@ enum usb_status usb_core_handle_it(struct usb_handle *pdev) return USBD_OK; } +static void usb_core_start_xfer(struct usb_handle *pdev, + void *handle, + struct usbd_ep *ep) +{ + if (ep->num == 0U) { + pdev->driver->ep0_start_xfer(handle, ep); + } else { + pdev->driver->ep_start_xfer(handle, ep); + } +} + /* * usb_core_receive * Receive an amount of data @@ -640,11 +651,7 @@ enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr, ep->is_in = false; ep->num = num; - if (num == 0U) { - pdev->driver->ep0_start_xfer(hpcd->instance, ep); - } else { - pdev->driver->ep_start_xfer(hpcd->instance, ep); - } + usb_core_start_xfer(pdev, hpcd->instance, ep); return USBD_OK; } @@ -678,11 +685,7 @@ enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr, ep->is_in = true; ep->num = num; - if (num == 0U) { - pdev->driver->ep0_start_xfer(hpcd->instance, ep); - } else { - pdev->driver->ep_start_xfer(hpcd->instance, ep); - } + usb_core_start_xfer(pdev, hpcd->instance, ep); return USBD_OK; } -- cgit v1.2.3 From f6f1b9b8c2b280e0423d07efe3a2bca3f854c9f8 Mon Sep 17 00:00:00 2001 From: Maksims Svecovs Date: Mon, 25 Oct 2021 16:13:42 +0100 Subject: chore(docs): update supported FVP models doc Update supported models list according to changes for v2.6 release in ci/tf-a-ci-scripts repository: * general FVP model update: d10c1b9 * gic600 update: aa2548a * CSS prebults model update: f1c3a4f Signed-off-by: Maksims Svecovs Change-Id: If2841f05238facb3cace7d5c8a78083d54f35e27 --- docs/plat/arm/fvp/index.rst | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst index d41982fb1..2aaf195a5 100644 --- a/docs/plat/arm/fvp/index.rst +++ b/docs/plat/arm/fvp/index.rst @@ -12,51 +12,50 @@ Arm FVPs without shifted affinities, and that do not support threaded CPU cores (64-bit host machine only). .. note:: - The FVP models used are Version 11.15 Build 14, unless otherwise stated. + The FVP models used are Version 11.16 Build 16, unless otherwise stated. -- ``FVP_Base_AEMvA`` -- ``FVP_Base_AEMv8A-AEMv8A`` +- ``Foundation_Platform`` - ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502`` -- ``FVP_Base_RevC-2xAEMvA`` -- ``FVP_Base_Cortex-A32x4`` (Version 11.12 build 38) +- ``FVP_Base_AEMv8A-AEMv8A`` (For certain configurations also uses 11.14/21) +- ``FVP_Base_AEMv8A-GIC600AE`` +- ``FVP_Base_AEMvA`` (For certain configurations also uses 0.0/6684) +- ``FVP_Base_Cortex-A32x4`` (Version 11.12/38) - ``FVP_Base_Cortex-A35x4`` - ``FVP_Base_Cortex-A53x4`` -- ``FVP_Base_Cortex-A55x4+Cortex-A75x4`` - ``FVP_Base_Cortex-A55x4`` +- ``FVP_Base_Cortex-A55x4+Cortex-A75x4`` - ``FVP_Base_Cortex-A57x1-A53x1`` - ``FVP_Base_Cortex-A57x2-A53x4`` - ``FVP_Base_Cortex-A57x4-A53x4`` - ``FVP_Base_Cortex-A57x4`` -- ``FVP_Base_Cortex-A65x4`` - ``FVP_Base_Cortex-A65AEx8`` +- ``FVP_Base_Cortex-A65x4`` +- ``FVP_Base_Cortex-A710x4`` - ``FVP_Base_Cortex-A72x4-A53x4`` - ``FVP_Base_Cortex-A72x4`` - ``FVP_Base_Cortex-A73x4-A53x4`` - ``FVP_Base_Cortex-A73x4`` - ``FVP_Base_Cortex-A75x4`` -- ``FVP_Base_Cortex-A76x4`` - ``FVP_Base_Cortex-A76AEx4`` - ``FVP_Base_Cortex-A76AEx8`` +- ``FVP_Base_Cortex-A76x4`` - ``FVP_Base_Cortex-A77x4`` - ``FVP_Base_Cortex-A78x4`` -- ``FVP_Base_Cortex-A710x4`` -- ``FVP_Morello`` (Version 0.10 build 542) - ``FVP_Base_Neoverse-E1x1`` - ``FVP_Base_Neoverse-E1x2`` - ``FVP_Base_Neoverse-E1x4`` - ``FVP_Base_Neoverse-N1x4`` - ``FVP_Base_Neoverse-N2x4`` (Version 11.12 build 38) - ``FVP_Base_Neoverse-V1x4`` -- ``FVP_CSS_SGI-575`` (Version 11.10 build 36) -- ``FVP_CSS_SGM-775`` -- ``FVP_RD_E1_edge`` (Version 11.9 build 41) -- ``FVP_RD_N1_edge`` (Version 11.10 build 36) -- ``FVP_RD_N1_edge_dual`` (Version 11.10 build 36) -- ``FVP_RD_Daniel`` (Version 11.13 build 10) -- ``FVP_RD_N2`` (Version 11.13 build 10) -- ``FVP_TC0`` (Version 0.0 build 6509) -- ``FVP_Base_AEMv8A-GIC600AE`` (Version 0.0 build 6415) -- ``Foundation_Platform`` +- ``FVP_Base_RevC-2xAEMvA`` (For certain configurations also uses 0.0/6557) +- ``FVP_CSS_SGI-575`` (Version 11.15/26) +- ``FVP_Morello`` (Version 0.11/19) +- ``FVP_RD_E1_edge`` (Version 11.15/26) +- ``FVP_RD_N1_edge_dual`` (Version 11.15/26) +- ``FVP_RD_N1_edge`` (Version 11.15/26) +- ``FVP_RD_V1`` (Version 11.15/26) +- ``FVP_TC0`` +- ``FVP_TC1`` The latest version of the AArch32 build of TF-A has been tested on the following Arm FVPs without shifted affinities, and that do not support threaded -- cgit v1.2.3 From a67ac7648cd814ed8f8d4ece1b265c6d48c6dc81 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 4 Nov 2021 13:47:17 +0000 Subject: fix(arm_fpga): avoid re-linking from executable ELF file When we build the convenience firmware package file for the Arm FPGA boards (bl31.axf), we combine trampolines, the DTB and the actual BL31 code into one ELF file, which is more a "container with load addresses" than an actual executable. So far ld was fine with us using bl31.elf as an input file, but binutils 2.35 changed that and complains about taking an *executable* ELF file as in *input* to the linker: ----------------- aarch64-none-elf-ld.bfd: cannot use executable file 'build/arm_fpga/debug/./bl31/bl31.elf' as input to a link ----------------- Fortunately we don't need the actual BL31 ELF file for *that* part of the linking, so can use the just created bl31.bin binary version of it. Actually that shrinks the file, as we needlessly included the .BSS section in the final file before. Using the binary works with both older and newer toolchains versions, so let's do this unconditionally. Change-Id: Ib7e697f8363499123f7cb860f118f182d0830768 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/build_axf.ld.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plat/arm/board/arm_fpga/build_axf.ld.S b/plat/arm/board/arm_fpga/build_axf.ld.S index b4bc7d884..d8254e5b2 100644 --- a/plat/arm/board/arm_fpga/build_axf.ld.S +++ b/plat/arm/board/arm_fpga/build_axf.ld.S @@ -15,11 +15,11 @@ OUTPUT_FORMAT("elf64-littleaarch64") OUTPUT_ARCH(aarch64) -INPUT(./bl31/bl31.elf) INPUT(./rom_trampoline.o) INPUT(./kernel_trampoline.o) TARGET(binary) +INPUT(./bl31.bin) INPUT(./fdts/arm_fpga.dtb) ENTRY(_start) @@ -33,7 +33,7 @@ SECTIONS .bl31 (BL31_BASE): { ASSERT(. == ALIGN(PAGE_SIZE), "BL31_BASE is not page aligned"); - *bl31.elf(.text* .data* .rodata* ro* .bss*) + *bl31.bin } .dtb (FPGA_PRELOADED_DTB_BASE): { -- cgit v1.2.3 From 4d585fe52feb231d5e73ec50a505122d5e9bf450 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 19 May 2021 09:37:21 +0100 Subject: feat(libfdt): also allow changing base address For platforms where we don't know the number of cores at compile time, the size of the GIC redistributor frame is then also undetermined, since it depends on this number of cores. On top of this the GICR base address can also change, when an unknown number of ITS frames (including zero) take up space between the distributor and redistributor. So while those two adjustments are done for independent reasons, the code for doing so is very similar, so we should utilise the existing fdt_adjust_gic_redist() function. Add an (optional) gicr_base parameters to the prototype, so callers can choose to also adjust this base address later, if needed. Change-Id: Id39c0ba83e7401fdff1944e86950bb7121f210e8 Signed-off-by: Andre Przywara --- common/fdt_fixup.c | 42 ++++++++++++++++++++++++------- include/common/fdt_fixup.h | 4 ++- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 1 + 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/common/fdt_fixup.c b/common/fdt_fixup.c index 46606fb6e..de02b46e8 100644 --- a/common/fdt_fixup.c +++ b/common/fdt_fixup.c @@ -398,6 +398,7 @@ int fdt_add_cpus_node(void *dtb, unsigned int afflv0, * fdt_adjust_gic_redist() - Adjust GICv3 redistributor size * @dtb: Pointer to the DT blob in memory * @nr_cores: Number of CPU cores on this system. + * @gicr_base: Base address of the first GICR frame, or ~0 if unchanged * @gicr_frame_size: Size of the GICR frame per core * * On a GICv3 compatible interrupt controller, the redistributor provides @@ -410,17 +411,19 @@ int fdt_add_cpus_node(void *dtb, unsigned int afflv0, * A GICv4 compatible redistributor uses four 64K pages per core, whereas GICs * without support for direct injection of virtual interrupts use two 64K pages. * The @gicr_frame_size parameter should be 262144 and 131072, respectively. + * Also optionally allow adjusting the GICR frame base address, when this is + * different due to ITS frames between distributor and redistributor. * * Return: 0 on success, negative error value otherwise. */ int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, - unsigned int gicr_frame_size) + uintptr_t gicr_base, unsigned int gicr_frame_size) { int offset = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-v3"); - uint64_t redist_size_64; - uint32_t redist_size_32; + uint64_t reg_64; + uint32_t reg_32; void *val; - int parent; + int parent, ret; int ac, sc; if (offset < 0) { @@ -437,13 +440,34 @@ int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, return -EINVAL; } + if (gicr_base != INVALID_BASE_ADDR) { + if (ac == 1) { + reg_32 = cpu_to_fdt32(gicr_base); + val = ®_32; + } else { + reg_64 = cpu_to_fdt64(gicr_base); + val = ®_64; + } + /* + * The redistributor base address is the second address in + * the "reg" entry, so we have to skip one address and one + * size cell. + */ + ret = fdt_setprop_inplace_namelen_partial(dtb, offset, + "reg", 3, + (ac + sc) * 4, + val, ac * 4); + if (ret < 0) { + return ret; + } + } + if (sc == 1) { - redist_size_32 = cpu_to_fdt32(nr_cores * gicr_frame_size); - val = &redist_size_32; + reg_32 = cpu_to_fdt32(nr_cores * gicr_frame_size); + val = ®_32; } else { - redist_size_64 = cpu_to_fdt64(nr_cores * - (uint64_t)gicr_frame_size); - val = &redist_size_64; + reg_64 = cpu_to_fdt64(nr_cores * (uint64_t)gicr_frame_size); + val = ®_64; } /* diff --git a/include/common/fdt_fixup.h b/include/common/fdt_fixup.h index 2e9d49d53..7a590b2dc 100644 --- a/include/common/fdt_fixup.h +++ b/include/common/fdt_fixup.h @@ -7,13 +7,15 @@ #ifndef FDT_FIXUP_H #define FDT_FIXUP_H +#define INVALID_BASE_ADDR ((uintptr_t)~0UL) + int dt_add_psci_node(void *fdt); int dt_add_psci_cpu_enable_methods(void *fdt); int fdt_add_reserved_memory(void *dtb, const char *node_name, uintptr_t base, size_t size); int fdt_add_cpus_node(void *dtb, unsigned int afflv0, unsigned int afflv1, unsigned int afflv2); -int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, +int fdt_adjust_gic_redist(void *dtb, unsigned int nr_cores, uintptr_t gicr_base, unsigned int gicr_frame_size); #endif /* FDT_FIXUP_H */ diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 2b5ca4af7..1ad64886c 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -224,6 +224,7 @@ static void fpga_prepare_dtb(void) INFO("Adjusting GICR DT region to cover %u cores\n", nr_cores); err = fdt_adjust_gic_redist(fdt, nr_cores, + INVALID_BASE_ADDR, fpga_get_redist_size()); if (err < 0) { ERROR("Error %d fixing up GIC DT node\n", err); -- cgit v1.2.3 From 73a643eed9d88910a09ca666bc7ab7f5e532324e Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 24 Aug 2021 10:03:57 +0100 Subject: feat(gicv3): introduce GIC component identification The GIC specification describes ID registers in each GIC register frame (PIDRx), which can be used to identify a GIC component. The Arm Ltd. GIC implementations use certain ID values to identify the distributor, the redistributors and other parts like ITSes. Introduce a function that reads those part number IDs, which are spread over two registers. The actual numbers are only meaningful in connection with a certain GIC model, which would need to be checked beforehand, by the caller. Change-Id: Ia6ff326a1e8b12664e4637bc8e2683d2b5c7721c Signed-off-by: Andre Przywara --- drivers/arm/gic/v3/gicv3_helpers.c | 15 +++++++++++++++ include/drivers/arm/arm_gicv3_common.h | 4 ++++ include/drivers/arm/gicv3.h | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index d752013e2..753d995d7 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -393,3 +393,18 @@ unsigned int gicv3_rdistif_get_number_frames(const uintptr_t gicr_frame) return count; } + +unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame) +{ + unsigned int part_id; + + /* + * The lower 8 bits of PIDR0, complemented by the lower 4 bits of + * PIDR1 contain a part number identifying the GIC component at a + * particular base address. + */ + part_id = mmio_read_32(gic_frame + GICD_PIDR0_GICV3) & 0xff; + part_id |= (mmio_read_32(gic_frame + GICD_PIDR1_GICV3) << 8) & 0xf00; + + return part_id; +} diff --git a/include/drivers/arm/arm_gicv3_common.h b/include/drivers/arm/arm_gicv3_common.h index e5df31136..d1e93be67 100644 --- a/include/drivers/arm/arm_gicv3_common.h +++ b/include/drivers/arm/arm_gicv3_common.h @@ -21,4 +21,8 @@ #define IIDR_MODEL_ARM_GIC_600AE U(0x0300043b) #define IIDR_MODEL_ARM_GIC_700 U(0x0400043b) +#define PIDR_COMPONENT_ARM_DIST U(0x492) +#define PIDR_COMPONENT_ARM_REDIST U(0x493) +#define PIDR_COMPONENT_ARM_ITS U(0x494) + #endif /* ARM_GICV3_COMMON_H */ diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index fa8946b16..973a58b67 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -104,6 +104,8 @@ #define GICD_IROUTER U(0x6000) #define GICD_IROUTERE U(0x8000) +#define GICD_PIDR0_GICV3 U(0xffe0) +#define GICD_PIDR1_GICV3 U(0xffe4) #define GICD_PIDR2_GICV3 U(0xffe8) #define IGRPMODR_SHIFT 5 @@ -324,6 +326,8 @@ static inline uintptr_t gicv3_redist_size(uint64_t typer_val) #endif } +unsigned int gicv3_get_component_partnum(const uintptr_t gic_frame); + static inline bool gicv3_is_intr_id_special_identifier(unsigned int id) { return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT); -- cgit v1.2.3 From 93b785f5ae66a6418581c304c83a346e8baa5aa3 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 19 May 2021 09:40:01 +0100 Subject: feat(arm_fpga): determine GICR base by probing When an Arm Ltd GIC (Arm GIC-[567]00) is instantiated with one or more ITSes, the ITS MMIO frames appear between the distributor and redistributor addresses. This makes the beginning of the redistributor region dependent on the existence and number of ITSes. To support various FPGA images, with and without ITSes, probe the addresses in question, to learn whether they accommodate an ITS or a redistributor. This can be safely done by looking at the PIDR[01] registers, which contain an ID code for each region, documented in the Arm GIC TRMs. We try to find all ITSes instantiated, and skip either two or four 64K frames, depending on GICv4.1 support. At some point we will find the first redistributor; this address we then update in the DTB. Change-Id: Iefb88c2afa989e044fe0b36b7020b56538c60b07 Signed-off-by: Andre Przywara --- include/drivers/arm/gicv3.h | 2 + plat/arm/board/arm_fpga/fpga_bl31_setup.c | 2 +- plat/arm/board/arm_fpga/fpga_gicv3.c | 78 ++++++++++++++++++++++++++++--- plat/arm/board/arm_fpga/fpga_private.h | 1 + 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index 973a58b67..5efefb693 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -303,6 +303,8 @@ #define GITS_CTLR_ENABLED_BIT BIT_32(0) #define GITS_CTLR_QUIESCENT_BIT BIT_32(1) +#define GITS_TYPER_VSGI BIT_64(39) + #ifndef __ASSEMBLER__ #include diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 1ad64886c..abe68ad2d 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -224,7 +224,7 @@ static void fpga_prepare_dtb(void) INFO("Adjusting GICR DT region to cover %u cores\n", nr_cores); err = fdt_adjust_gic_redist(fdt, nr_cores, - INVALID_BASE_ADDR, + fpga_get_redist_base(), fpga_get_redist_size()); if (err < 0) { ERROR("Error %d fixing up GIC DT node\n", err); diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c index 4a97beb96..c379e7d03 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -1,13 +1,14 @@ /* - * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include -#include +#include #include +#include #include #include @@ -21,6 +22,7 @@ static const interrupt_prop_t fpga_interrupt_props[] = { }; static uintptr_t fpga_rdistif_base_addrs[PLATFORM_CORE_COUNT]; +static int nr_itses; static unsigned int fpga_mpidr_to_core_pos(unsigned long mpidr) { @@ -38,6 +40,8 @@ static gicv3_driver_data_t fpga_gicv3_driver_data = { void plat_fpga_gic_init(void) { const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; + uintptr_t gicr_base = 0U; + uint32_t iidr; int node, ret; node = fdt_node_offset_by_compatible(fdt, 0, "arm,gic-v3"); @@ -54,11 +58,66 @@ void plat_fpga_gic_init(void) return; } - ret = fdt_get_reg_props_by_index(fdt, node, 1, - &fpga_gicv3_driver_data.gicr_base, NULL); - if (ret < 0) { - WARN("Could not read GIC redistributor address from DT.\n"); - return; + iidr = mmio_read_32(fpga_gicv3_driver_data.gicd_base + GICD_IIDR); + if (((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_600) || + ((iidr & IIDR_MODEL_MASK) == IIDR_MODEL_ARM_GIC_700)) { + unsigned int frame_id; + + /* + * According to the GIC TRMs, if there are any ITSes, they + * start four 64K pages after the distributor. After all + * the ITSes then follow the redistributors. + */ + gicr_base = fpga_gicv3_driver_data.gicd_base + (4U << 16); + + do { + uint64_t its_typer; + + /* Each GIC component can be identified by its ID. */ + frame_id = gicv3_get_component_partnum(gicr_base); + + if (frame_id == PIDR_COMPONENT_ARM_REDIST) { + INFO("Found %d ITSes, redistributors start at 0x%llx\n", + nr_itses, (unsigned long long)gicr_base); + break; + } + + if (frame_id != PIDR_COMPONENT_ARM_ITS) { + WARN("GICv3: found unexpected frame 0x%x\n", + frame_id); + gicr_base = 0U; + break; + } + + /* + * Found an ITS, now work out if it supports virtual + * SGIs (for direct guest injection). If yes, each + * ITS occupies four 64K pages, otherwise just two. + */ + its_typer = mmio_read_64(gicr_base + GITS_TYPER); + if ((its_typer & GITS_TYPER_VSGI) != 0U) { + gicr_base += 4U << 16; + } else { + gicr_base += 2U << 16; + } + nr_itses++; + } while (true); + } + + /* + * If this is not a GIC-600 or -700, or the autodetection above failed, + * use the base address from the device tree. + */ + if (gicr_base == 0U) { + ret = fdt_get_reg_props_by_index(fdt, node, 1, + &fpga_gicv3_driver_data.gicr_base, + NULL); + if (ret < 0) { + WARN("Could not read GIC redistributor address from DT.\n"); + return; + } + } else { + fpga_gicv3_driver_data.gicr_base = gicr_base; } gicv3_driver_init(&fpga_gicv3_driver_data); @@ -91,3 +150,8 @@ uintptr_t fpga_get_redist_size(void) return gicv3_redist_size(typer_val); } + +uintptr_t fpga_get_redist_base(void) +{ + return fpga_gicv3_driver_data.gicr_base; +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index cc809c4e4..61c8992cd 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -26,6 +26,7 @@ void fpga_pwr_gic_off(void); unsigned int plat_fpga_calc_core_pos(uint32_t mpid); unsigned int fpga_get_nr_gic_cores(void); uintptr_t fpga_get_redist_size(void); +uintptr_t fpga_get_redist_base(void); #endif /* __ASSEMBLER__ */ -- cgit v1.2.3 From d7e39c43f2f58aabb085ed7b8f461f9ece6002d0 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Tue, 20 Jul 2021 20:05:38 +0100 Subject: feat(arm_fpga): add ITS autodetection Some FPGAs come with a GIC that has an ITS block configured. Since the ITS sits between the distributor and redistributors, we can autodetect that, and already adjust the GICR base address. To also make this ITS usable, add an ITS node to our base DTB, and remove that should we not find an ITS during the scan for the redistributor. This allows to use the same TF-A binary for FPGA images with or without an ITS. Change-Id: I4c0417dec7bccdbad8cbca26fa2634950fc50a66 Signed-off-by: Andre Przywara --- fdts/arm_fpga.dts | 7 +++++++ plat/arm/board/arm_fpga/fpga_bl31_setup.c | 10 ++++++++++ plat/arm/board/arm_fpga/fpga_gicv3.c | 5 +++++ plat/arm/board/arm_fpga/fpga_private.h | 1 + 4 files changed, 23 insertions(+) diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts index b7b4f0e6a..aad0a04d1 100644 --- a/fdts/arm_fpga.dts +++ b/fdts/arm_fpga.dts @@ -98,5 +98,12 @@ /* The GICR size will be adjusted at runtime to match the cores. */ <0x0 0x30040000 0x0 0x00020000>; /* GICR for one core */ interrupts = ; + + its: msi-controller@30040000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x30040000 0x0 0x40000>; + #msi-cells = <1>; + msi-controller; + }; }; }; diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index abe68ad2d..31c36151d 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -242,6 +242,16 @@ static void fpga_prepare_dtb(void) } } + /* Check whether we have an ITS. Remove the DT node if not. */ + if (!fpga_has_its()) { + int node = fdt_node_offset_by_compatible(fdt, 0, + "arm,gic-v3-its"); + + if (node >= 0) { + fdt_del_node(fdt, node); + } + } + err = fdt_pack(fdt); if (err < 0) { ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, err); diff --git a/plat/arm/board/arm_fpga/fpga_gicv3.c b/plat/arm/board/arm_fpga/fpga_gicv3.c index c379e7d03..e06a9da56 100644 --- a/plat/arm/board/arm_fpga/fpga_gicv3.c +++ b/plat/arm/board/arm_fpga/fpga_gicv3.c @@ -155,3 +155,8 @@ uintptr_t fpga_get_redist_base(void) { return fpga_gicv3_driver_data.gicr_base; } + +bool fpga_has_its(void) +{ + return nr_itses > 0; +} diff --git a/plat/arm/board/arm_fpga/fpga_private.h b/plat/arm/board/arm_fpga/fpga_private.h index 61c8992cd..84d651cea 100644 --- a/plat/arm/board/arm_fpga/fpga_private.h +++ b/plat/arm/board/arm_fpga/fpga_private.h @@ -27,6 +27,7 @@ unsigned int plat_fpga_calc_core_pos(uint32_t mpid); unsigned int fpga_get_nr_gic_cores(void); uintptr_t fpga_get_redist_size(void); uintptr_t fpga_get_redist_base(void); +bool fpga_has_its(void); #endif /* __ASSEMBLER__ */ -- cgit v1.2.3 From 49e789e353efaf97f84eca016c6a1b8a2b3e3d98 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 2 Sep 2021 17:00:06 +0100 Subject: fix(fdt): avoid output on missing DT property When we use our fdt_read_uint32* helper functions, we output a warning on not finding the requested property. However non-existing properties are not that uncommon, and *trying* to read such a property is actually a nice way of checking its existence. Since we already return a specific error value in this case, the caller can easily check this and give a more specific error message, if needed. When the caller decides to properly handle the error (fallback, default value, etc), a message on the console is quite misleading. Demote the message to a VERBOSE, so normal builds will not spam the console with pointless messages. Change-Id: I7a279a4ee0147c5f4a0503d0a8745c6cfea58be5 Signed-off-by: Andre Przywara --- common/fdt_wrappers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 64e01ea6d..cfa134243 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -35,7 +35,7 @@ int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, /* Access property and obtain its length (in bytes) */ prop = fdt_getprop(dtb, node, prop_name, &value_len); if (prop == NULL) { - WARN("Couldn't find property %s in dtb\n", prop_name); + VERBOSE("Couldn't find property %s in dtb\n", prop_name); return -FDT_ERR_NOTFOUND; } -- cgit v1.2.3 From 52b8f4465e48165695440e730039b2a99517b4b7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 1 Sep 2021 11:54:30 +0100 Subject: refactor(arm_fpga): move command line code into separate function The code dealing with finding the command line and inserting that into the DTB is somewhat large, and drowns the other DT handlers in our fpga_prepare_dtb() function. Move that code into a separate function, to improve readability. Change-Id: I828203c4bb248d38a2562fcb6afdefedf3179f8d Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 105 ++++++++++++++++-------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 31c36151d..86f00ab05 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -132,6 +132,57 @@ unsigned int plat_get_syscnt_freq2(void) FPGA_DEFAULT_TIMER_FREQUENCY); } +#define CMDLINE_SIGNATURE "CMD:" + +static int fpga_dtb_set_commandline(void *fdt, const char *cmdline) +{ + int chosen; + const char *eol; + char nul = 0; + int slen, err; + + chosen = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen == -FDT_ERR_EXISTS) { + chosen = fdt_path_offset(fdt, "/chosen"); + } + + if (chosen < 0) { + return chosen; + } + + /* + * There is most likely an EOL at the end of the + * command line, make sure we terminate the line there. + * We can't replace the EOL with a NUL byte in the + * source, as this is in read-only memory. So we first + * create the property without any termination, then + * append a single NUL byte. + */ + eol = strchr(cmdline, '\n'); + if (eol == NULL) { + eol = strchr(cmdline, 0); + } + /* Skip the signature and omit the EOL/NUL byte. */ + slen = eol - (cmdline + strlen(CMDLINE_SIGNATURE)); + /* + * Let's limit the size of the property, just in case + * we find the signature by accident. The Linux kernel + * limits to 4096 characters at most (in fact 2048 for + * arm64), so that sounds like a reasonable number. + */ + if (slen > 4095) { + slen = 4095; + } + + err = fdt_setprop(fdt, chosen, "bootargs", + cmdline + strlen(CMDLINE_SIGNATURE), slen); + if (err != 0) { + return err; + } + + return fdt_appendprop(fdt, chosen, "bootargs", &nul, 1); +} + static void fpga_prepare_dtb(void) { void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; @@ -151,55 +202,13 @@ static void fpga_prepare_dtb(void) } /* Check for the command line signature. */ - if (!strncmp(cmdline, "CMD:", 4)) { - int chosen; - - INFO("using command line at 0x%x\n", FPGA_PRELOADED_CMD_LINE); - - chosen = fdt_add_subnode(fdt, 0, "chosen"); - if (chosen == -FDT_ERR_EXISTS) { - chosen = fdt_path_offset(fdt, "/chosen"); - } - if (chosen < 0) { - ERROR("cannot find /chosen node: %d\n", chosen); + if (!strncmp(cmdline, CMDLINE_SIGNATURE, strlen(CMDLINE_SIGNATURE))) { + err = fpga_dtb_set_commandline(fdt, cmdline); + if (err == 0) { + INFO("using command line at 0x%x\n", + FPGA_PRELOADED_CMD_LINE); } else { - const char *eol; - char nul = 0; - int slen; - - /* - * There is most likely an EOL at the end of the - * command line, make sure we terminate the line there. - * We can't replace the EOL with a NUL byte in the - * source, as this is in read-only memory. So we first - * create the property without any termination, then - * append a single NUL byte. - */ - eol = strchr(cmdline, '\n'); - if (!eol) { - eol = strchr(cmdline, 0); - } - /* Skip the signature and omit the EOL/NUL byte. */ - slen = eol - (cmdline + 4); - - /* - * Let's limit the size of the property, just in case - * we find the signature by accident. The Linux kernel - * limits to 4096 characters at most (in fact 2048 for - * arm64), so that sounds like a reasonable number. - */ - if (slen > 4095) { - slen = 4095; - } - err = fdt_setprop(fdt, chosen, "bootargs", - cmdline + 4, slen); - if (!err) { - err = fdt_appendprop(fdt, chosen, "bootargs", - &nul, 1); - } - if (err) { - ERROR("Could not set command line: %d\n", err); - } + ERROR("failed to put command line into DTB: %d\n", err); } } -- cgit v1.2.3 From d850169c9c233c4bc413d8319196557b54683688 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 1 Sep 2021 11:59:08 +0100 Subject: feat(arm_fpga): query PL011 to learn system frequency The Arm FPGAs run in mostly one clock domain, which is used for the CPU cores, the generic timer, and also the UART baudrate base clock. This single clock can have different rates, to compensate for different IP complexity. So far most images used 10 MHz, but different rates start to appear. To avoid patching both the arch timer frequency and UART baud base fixed clock in the DTB manually, we would like to set the clock rate automatically. Fortunately the SCP firmware has the actual clock rate hard coded, and already programs the PL011 UART baud divider register with the correct value to achieve a 38400 bps baudrate. So read the two PL011 baudrate divider values and re-calculate the original base clock from there, to use as the arch timer frequency. If the arch timer DT node contains a clock-frequency property, we use that instead, to support overriding and disabling this autodetection. Change-Id: I9857fbb418deb4644aeb2816f1102796f9bfd3bb Signed-off-by: Andre Przywara --- fdts/arm_fpga.dts | 1 - plat/arm/board/arm_fpga/fpga_bl31_setup.c | 89 ++++++++++++++++++++++++++++--- 2 files changed, 83 insertions(+), 7 deletions(-) diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts index aad0a04d1..b9435a241 100644 --- a/fdts/arm_fpga.dts +++ b/fdts/arm_fpga.dts @@ -40,7 +40,6 @@ timer { compatible = "arm,armv8-timer"; - clock-frequency = <10000000>; interrupts = , , , diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 86f00ab05..80a70145e 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "fpga_private.h" @@ -118,18 +119,94 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) } } -unsigned int plat_get_syscnt_freq2(void) +/* + * Even though we sell the FPGA UART as an SBSA variant, it is actually + * a full fledged PL011. So the baudrate divider registers exist. + */ +#ifndef UARTIBRD +#define UARTIBRD 0x024 +#define UARTFBRD 0x028 +#endif + +/* Round an integer to the closest multiple of a value. */ +static unsigned int round_multiple(unsigned int x, unsigned int multiple) +{ + if (multiple < 2) { + return x; + } + + return ((x + (multiple / 2 - 1)) / multiple) * multiple; +} + +#define PL011_FRAC_SHIFT 6 +#define FPGA_DEFAULT_BAUDRATE 38400 +#define PL011_OVERSAMPLING 16 +static unsigned int pl011_freq_from_divider(unsigned int divider) +{ + unsigned int freq; + + freq = divider * FPGA_DEFAULT_BAUDRATE * PL011_OVERSAMPLING; + + return freq >> PL011_FRAC_SHIFT; +} + +/* + * The FPGAs run most peripherals from one main clock, among them the CPUs, + * the arch timer, and the UART baud base clock. + * The SCP knows this frequency and programs the UART clock divider for a + * 38400 bps baudrate. Recalculate the base input clock from there. + */ +static unsigned int fpga_get_system_frequency(void) { const void *fdt = (void *)(uintptr_t)FPGA_PRELOADED_DTB_BASE; - int node; + int node, err; + /* + * If the arch timer DT node has an explicit clock-frequency property + * set, use that, to allow people overriding auto-detection. + */ node = fdt_node_offset_by_compatible(fdt, 0, "arm,armv8-timer"); - if (node < 0) { - return FPGA_DEFAULT_TIMER_FREQUENCY; + if (node >= 0) { + uint32_t freq; + + err = fdt_read_uint32(fdt, node, "clock-frequency", &freq); + if (err >= 0) { + return freq; + } } - return fdt_read_uint32_default(fdt, node, "clock-frequency", - FPGA_DEFAULT_TIMER_FREQUENCY); + node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011"); + if (node >= 0) { + uintptr_t pl011_base; + unsigned int divider; + + err = fdt_get_reg_props_by_index(fdt, node, 0, + &pl011_base, NULL); + if (err >= 0) { + divider = mmio_read_32(pl011_base + UARTIBRD); + divider <<= PL011_FRAC_SHIFT; + divider += mmio_read_32(pl011_base + UARTFBRD); + + /* + * The result won't be exact, due to rounding errors, + * but the input frequency was a multiple of 250 KHz. + */ + return round_multiple(pl011_freq_from_divider(divider), + 250000); + } else { + WARN("Cannot read PL011 MMIO base\n"); + } + } else { + WARN("No PL011 DT node\n"); + } + + /* No PL011 DT node or calculation failed. */ + return FPGA_DEFAULT_TIMER_FREQUENCY; +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return fpga_get_system_frequency(); } #define CMDLINE_SIGNATURE "CMD:" -- cgit v1.2.3 From 422b44fb56db7ca8b1a2f9f706733d7d4c2fdeb1 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 1 Sep 2021 11:59:57 +0100 Subject: feat(arm_fpga): write UART baud base clock frequency into DTB Since we now autodetect the actual system frequency, which is also used as the base for the UART baudrate generation, we should update the value currently hard-coded in the DT. Otherwise Linux will reprogram the divider using a potentially wrong base rate, which breaks the UART output. Find the DT node referenced by the UART node as the clock rate, and set the "clock-frequency" property in that node to the detected system frequency. This will let Linux reprogram the divider to the same value, preserving the actual baudrate. Change-Id: Ib5a936849f2198577b86509f032751d5386ed2f8 Signed-off-by: Andre Przywara --- plat/arm/board/arm_fpga/fpga_bl31_setup.c | 47 ++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/fpga_bl31_setup.c b/plat/arm/board/arm_fpga/fpga_bl31_setup.c index 80a70145e..e1b3abb28 100644 --- a/plat/arm/board/arm_fpga/fpga_bl31_setup.c +++ b/plat/arm/board/arm_fpga/fpga_bl31_setup.c @@ -21,6 +21,7 @@ #include static entry_point_info_t bl33_image_ep_info; +static unsigned int system_freq; volatile uint32_t secondary_core_spinlock; uintptr_t plat_get_ns_image_entrypoint(void) @@ -206,7 +207,49 @@ static unsigned int fpga_get_system_frequency(void) unsigned int plat_get_syscnt_freq2(void) { - return fpga_get_system_frequency(); + if (system_freq == 0U) { + system_freq = fpga_get_system_frequency(); + } + + return system_freq; +} + +static void fpga_dtb_update_clock(void *fdt, unsigned int freq) +{ + uint32_t freq_dtb = fdt32_to_cpu(freq); + uint32_t phandle; + int node, err; + + node = fdt_node_offset_by_compatible(fdt, 0, "arm,pl011"); + if (node < 0) { + WARN("%s(): No PL011 DT node found\n", __func__); + + return; + } + + err = fdt_read_uint32(fdt, node, "clocks", &phandle); + if (err != 0) { + WARN("Cannot find clocks property\n"); + + return; + } + + node = fdt_node_offset_by_phandle(fdt, phandle); + if (node < 0) { + WARN("Cannot get phandle\n"); + + return; + } + + err = fdt_setprop_inplace(fdt, node, + "clock-frequency", + &freq_dtb, + sizeof(freq_dtb)); + if (err < 0) { + WARN("Could not update DT baud clock frequency\n"); + + return; + } } #define CMDLINE_SIGNATURE "CMD:" @@ -318,6 +361,8 @@ static void fpga_prepare_dtb(void) } } + fpga_dtb_update_clock(fdt, system_freq); + /* Check whether we support the SPE PMU. Remove the DT node if not. */ if (!spe_supported()) { int node = fdt_node_offset_by_compatible(fdt, 0, -- cgit v1.2.3 From 195381a91313bc0bce2cfa087f3c55136a9e8496 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 14 May 2021 16:13:55 +0100 Subject: fix(arm_fpga): Change PL011 UART IRQ About a year ago there was a change in the underlying Arm platform design framework, which lead to a reorganisation of the interrupt map (to make room for multi-chip designs). This lead to the PL011 debug UART interrupt to move from SPI 115 to SPI 415. Unfortunately there is not a good or easy way to auto-detect this change: Flooding the TX FIFO and checking GICD_ISPENDR registers might be possible, but sounds a bit over the top for BL31. So we would need to break one group of images: newer ones, as we do right now, or older ones. By now every interesting FPGA image seems to use the newer IRQ, so in the interest of having a smooth experience for most users, lets switch to this IRQ. When people are interested in older images, they can either change the number back in the .dts file, or provide a patched DTB on the FPGA command line. Change-Id: I3c7e7b711f5142813bd94eecde3095a4fc555bb3 Signed-off-by: Andre Przywara --- fdts/arm_fpga.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdts/arm_fpga.dts b/fdts/arm_fpga.dts index b7b4f0e6a..0fca30cbf 100644 --- a/fdts/arm_fpga.dts +++ b/fdts/arm_fpga.dts @@ -82,7 +82,7 @@ dbg_uart: serial@7ff80000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x7ff80000 0x0 0x00001000>; - interrupts = ; + interrupts = ; clocks = <&uartclk>, <&bus_refclk>; clock-names = "uartclk", "apb_pclk"; }; -- cgit v1.2.3 From 5819e23bc47c860872141caf42bddddb1b8679a5 Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Wed, 6 Oct 2021 15:31:24 -0700 Subject: fix(errata): workaround for Neoverse-N2 erratum 2242415 Neoverse-N2 erratum 2242415 is a Cat B erratum that applies to revision r0p0 of CPU. It is still open. The workaround is to set CPUACTLR_EL1[22] to 1'b1. Setting CPUACTLR_EL1[22] will cause CFP instruction to invalidate all branch predictor resources regardless of context. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest Signed-off-by: nayanpatel-arm Change-Id: I442be81fbc32e21fed51a84f59584df17f845e96 --- docs/design/cpu-specific-build-macros.rst | 11 +++++----- include/lib/cpus/aarch64/neoverse_n2.h | 1 + lib/cpus/aarch64/neoverse_n2.S | 34 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index eebeaa251..b19c534cb 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -340,11 +340,6 @@ For Neoverse N1, the following errata build flags are defined : CPU. This needs to be enabled for revisions r3p0, r3p1, r4p0, and r4p1, for revisions r0p0, r1p0, and r2p0 there is no workaround. -For Neoverse N2, the following errata build flags are defined : - -- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2 - CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open. - For Neoverse V1, the following errata build flags are defined : - ``ERRATA_V1_1774420``: This applies errata 1774420 workaround to Neoverse-V1 @@ -407,6 +402,9 @@ For Cortex-A710, the following errata build flags are defined : For Neoverse N2, the following errata build flags are defined : +- ``ERRATA_N2_2002655``: This applies errata 2002655 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU, it is still open. + - ``ERRATA_N2_2067956``: This applies errata 2067956 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. @@ -422,6 +420,9 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2138953``: This applies errata 2138953 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. + DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h index f414cb53c..8ba62a3f7 100644 --- a/include/lib/cpus/aarch64/neoverse_n2.h +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -28,6 +28,7 @@ ******************************************************************************/ #define NEOVERSE_N2_CPUACTLR_EL1 S3_0_C15_C1_0 #define NEOVERSE_N2_CPUACTLR_EL1_BIT_46 (ULL(1) << 46) +#define NEOVERSE_N2_CPUACTLR_EL1_BIT_22 (ULL(1) << 22) /******************************************************************************* * CPU Auxiliary Control register 2 specific definitions. diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index 330cc596a..c197590ba 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -183,6 +183,34 @@ func check_errata_2138956 b cpu_rev_var_ls endfunc check_errata_2138956 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2242415. + * This applies to revision r0p0 of Neoverse N2. it is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2242415_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2242415 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mrs x1, NEOVERSE_N2_CPUACTLR_EL1 + orr x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22 + msr NEOVERSE_N2_CPUACTLR_EL1, x1 +1: + ret x17 +endfunc errata_n2_2242415_wa + +func check_errata_2242415 + /* Applies to r0p0 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2242415 + /* -------------------------------------------------- * Errata Workaround for Neoverse N2 Erratum 2138953. * This applies to revision r0p0 of Neoverse N2. it is still open. @@ -258,6 +286,11 @@ func neoverse_n2_reset_func bl errata_n2_2138953_wa #endif +#if ERRATA_N2_2242415 + mov x0, x18 + bl errata_n2_2242415_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, cptr_el3 @@ -324,6 +357,7 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2189731, neoverse_n2, 2189731 report_errata ERRATA_N2_2138956, neoverse_n2, 2138956 report_errata ERRATA_N2_2138953, neoverse_n2, 2138953 + report_errata ERRATA_N2_2242415, neoverse_n2, 2242415 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 138f7a572..4224fcc65 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -461,6 +461,10 @@ ERRATA_N2_2138956 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2138953 ?=0 +# Flag to apply erratum 2242415 workaround during reset. This erratum applies +# to revision r0p0 of the Neoverse N2 cpu and is still open. +ERRATA_N2_2242415 ?=0 + # Flag to apply erratum 2055002 workaround during reset. This erratum applies # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2055002 ?=0 @@ -862,6 +866,10 @@ $(eval $(call add_define,ERRATA_N2_2138956)) $(eval $(call assert_boolean,ERRATA_N2_2138953)) $(eval $(call add_define,ERRATA_N2_2138953)) +# Process ERRATA_N2_2242415 flag +$(eval $(call assert_boolean,ERRATA_N2_2242415)) +$(eval $(call add_define,ERRATA_N2_2242415)) + # Process ERRATA_A710_2055002 flag $(eval $(call assert_boolean,ERRATA_A710_2055002)) $(eval $(call add_define,ERRATA_A710_2055002)) -- cgit v1.2.3 From c948185c973c13df36c62c4bcb50e22b14d6e06a Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Wed, 20 Oct 2021 18:28:58 -0700 Subject: fix(errata): workaround for Neoverse-N2 erratum 2138958 Neoverse-N2 erratum 2138958 is a Cat B erratum that applies to revision r0p0 of CPU. It is still open. The workaround is to set CPUACTLR5_EL1[13] to 1'b1. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest Signed-off-by: nayanpatel-arm Change-Id: I5247f8f8eef08d38c169aad6d2c5501ac387c720 --- docs/design/cpu-specific-build-macros.rst | 3 +++ include/lib/cpus/aarch64/neoverse_n2.h | 1 + lib/cpus/aarch64/neoverse_n2.S | 34 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 4 files changed, 46 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index b19c534cb..cd4d0fdca 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -423,6 +423,9 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2242415``: This applies errata 2242415 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2138958``: This applies errata 2138958 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. + DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h index 8ba62a3f7..a457f2a54 100644 --- a/include/lib/cpus/aarch64/neoverse_n2.h +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -41,6 +41,7 @@ ******************************************************************************/ #define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44) +#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13) /******************************************************************************* * CPU Auxiliary Control register specific definitions. diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index c197590ba..ff569fb23 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -240,6 +240,34 @@ func check_errata_2138953 b cpu_rev_var_ls endfunc check_errata_2138953 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2138958. + * This applies to revision r0p0 of Neoverse N2. it is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2138958_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2138958 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mrs x1, NEOVERSE_N2_CPUACTLR5_EL1 + orr x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_13 + msr NEOVERSE_N2_CPUACTLR5_EL1, x1 +1: + ret x17 +endfunc errata_n2_2138958_wa + +func check_errata_2138958 + /* Applies to r0p0 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2138958 + /* ------------------------------------------- * The CPU Ops reset function for Neoverse N2. * ------------------------------------------- @@ -291,6 +319,11 @@ func neoverse_n2_reset_func bl errata_n2_2242415_wa #endif +#if ERRATA_N2_2138958 + mov x0, x18 + bl errata_n2_2138958_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, cptr_el3 @@ -358,6 +391,7 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2138956, neoverse_n2, 2138956 report_errata ERRATA_N2_2138953, neoverse_n2, 2138953 report_errata ERRATA_N2_2242415, neoverse_n2, 2242415 + report_errata ERRATA_N2_2138958, neoverse_n2, 2138958 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 4224fcc65..b676987d7 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -465,6 +465,10 @@ ERRATA_N2_2138953 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2242415 ?=0 +# Flag to apply erratum 2138958 workaround during reset. This erratum applies +# to revision r0p0 of the Neoverse N2 cpu and is still open. +ERRATA_N2_2138958 ?=0 + # Flag to apply erratum 2055002 workaround during reset. This erratum applies # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2055002 ?=0 @@ -870,6 +874,10 @@ $(eval $(call add_define,ERRATA_N2_2138953)) $(eval $(call assert_boolean,ERRATA_N2_2242415)) $(eval $(call add_define,ERRATA_N2_2242415)) +# Process ERRATA_N2_2138958 flag +$(eval $(call assert_boolean,ERRATA_N2_2138958)) +$(eval $(call add_define,ERRATA_N2_2138958)) + # Process ERRATA_A710_2055002 flag $(eval $(call assert_boolean,ERRATA_A710_2055002)) $(eval $(call add_define,ERRATA_A710_2055002)) -- cgit v1.2.3 From 603806d1376c4b18211fb1d4cc338153de026c32 Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Thu, 7 Oct 2021 17:59:33 -0700 Subject: fix(errata): workaround for Neoverse-N2 erratum 2242400 Neoverse-N2 erratum 2242400 is a Cat B erratum that applies to revision r0p0 of CPU. It is still open. The workaround is to set CPUACTLR5_EL1[17] to 1'b1 followed by setting few system control registers to specific values as per attached SDEN document. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest Signed-off-by: nayanpatel-arm Change-Id: I6a9cb4a23238b8b511802a1ee9fcc5b207137649 --- docs/design/cpu-specific-build-macros.rst | 3 ++ include/lib/cpus/aarch64/neoverse_n2.h | 1 + lib/cpus/aarch64/neoverse_n2.S | 51 ++++++++++++++++++++++++++++--- lib/cpus/cpu-ops.mk | 8 +++++ 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index cd4d0fdca..74be11bc6 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -426,6 +426,9 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2138958``: This applies errata 2138958 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2242400``: This applies errata 2242400 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. + DSU Errata Workarounds ---------------------- diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h index a457f2a54..a1e676ec2 100644 --- a/include/lib/cpus/aarch64/neoverse_n2.h +++ b/include/lib/cpus/aarch64/neoverse_n2.h @@ -42,6 +42,7 @@ #define NEOVERSE_N2_CPUACTLR5_EL1 S3_0_C15_C8_0 #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_44 (ULL(1) << 44) #define NEOVERSE_N2_CPUACTLR5_EL1_BIT_13 (ULL(1) << 13) +#define NEOVERSE_N2_CPUACTLR5_EL1_BIT_17 (ULL(1) << 17) /******************************************************************************* * CPU Auxiliary Control register specific definitions. diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index ff569fb23..869aa41e1 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -268,6 +268,43 @@ func check_errata_2138958 b cpu_rev_var_ls endfunc check_errata_2138958 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2242400. + * This applies to revision r0p0 of Neoverse N2. it is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2242400_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2242400 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mrs x1, NEOVERSE_N2_CPUACTLR5_EL1 + orr x1, x1, NEOVERSE_N2_CPUACTLR5_EL1_BIT_17 + msr NEOVERSE_N2_CPUACTLR5_EL1, x1 + ldr x0, =0x2 + msr S3_6_c15_c8_0, x0 + ldr x0, =0x10F600E000 + msr S3_6_c15_c8_2, x0 + ldr x0, =0x10FF80E000 + msr S3_6_c15_c8_3, x0 + ldr x0, =0x80000000003FF + msr S3_6_c15_c8_1, x0 + isb +1: + ret x17 +endfunc errata_n2_2242400_wa + +func check_errata_2242400 + /* Applies to r0p0 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2242400 + /* ------------------------------------------- * The CPU Ops reset function for Neoverse N2. * ------------------------------------------- @@ -294,13 +331,13 @@ func neoverse_n2_reset_func #endif #if ERRATA_N2_2025414 - mov x0, x18 - bl errata_n2_2025414_wa + mov x0, x18 + bl errata_n2_2025414_wa #endif #if ERRATA_N2_2189731 - mov x0, x18 - bl errata_n2_2189731_wa + mov x0, x18 + bl errata_n2_2189731_wa #endif @@ -324,6 +361,11 @@ func neoverse_n2_reset_func bl errata_n2_2138958_wa #endif +#if ERRATA_N2_2242400 + mov x0, x18 + bl errata_n2_2242400_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, cptr_el3 @@ -392,6 +434,7 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2138953, neoverse_n2, 2138953 report_errata ERRATA_N2_2242415, neoverse_n2, 2242415 report_errata ERRATA_N2_2138958, neoverse_n2, 2138958 + report_errata ERRATA_N2_2242400, neoverse_n2, 2242400 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index b676987d7..f0da13919 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -469,6 +469,10 @@ ERRATA_N2_2242415 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2138958 ?=0 +# Flag to apply erratum 2242400 workaround during reset. This erratum applies +# to revision r0p0 of the Neoverse N2 cpu and is still open. +ERRATA_N2_2242400 ?=0 + # Flag to apply erratum 2055002 workaround during reset. This erratum applies # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2055002 ?=0 @@ -878,6 +882,10 @@ $(eval $(call add_define,ERRATA_N2_2242415)) $(eval $(call assert_boolean,ERRATA_N2_2138958)) $(eval $(call add_define,ERRATA_N2_2138958)) +# Process ERRATA_N2_2242400 flag +$(eval $(call assert_boolean,ERRATA_N2_2242400)) +$(eval $(call add_define,ERRATA_N2_2242400)) + # Process ERRATA_A710_2055002 flag $(eval $(call assert_boolean,ERRATA_A710_2055002)) $(eval $(call add_define,ERRATA_A710_2055002)) -- cgit v1.2.3 From 0d2d99924e1be548e75c46cfd536f7503cf863e0 Mon Sep 17 00:00:00 2001 From: nayanpatel-arm Date: Wed, 20 Oct 2021 17:30:46 -0700 Subject: fix(errata): workaround for Neoverse-N2 erratum 2280757 Neoverse-N2 erratum 2280757 is a Cat B erratum that applies to revision r0p0 of CPU. It is still open. The workaround is to set CPUACTLR_EL1[22] to 1'b1. Setting CPUACTLR_EL1[22] will cause CFP instruction to invalidate all branch predictor resources regardless of context. SDEN can be found here: https://developer.arm.com/documentation/SDEN1982442/latest Signed-off-by: nayanpatel-arm Change-Id: I615bcc1f993c45659b8b6f1a34fca0eb490f8add --- docs/design/cpu-specific-build-macros.rst | 3 +++ lib/cpus/aarch64/neoverse_n2.S | 34 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 8 ++++++++ 3 files changed, 45 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 74be11bc6..b5ec36318 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -429,6 +429,9 @@ For Neoverse N2, the following errata build flags are defined : - ``ERRATA_N2_2242400``: This applies errata 2242400 workaround to Neoverse-N2 CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. +- ``ERRATA_N2_2280757``: This applies errata 2280757 workaround to Neoverse-N2 + CPU. This needs to be enabled for revision r0p0 of the CPU and is still open. + DSU Errata Workarounds ---------------------- diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S index 869aa41e1..621aded7c 100644 --- a/lib/cpus/aarch64/neoverse_n2.S +++ b/lib/cpus/aarch64/neoverse_n2.S @@ -305,6 +305,34 @@ func check_errata_2242400 b cpu_rev_var_ls endfunc check_errata_2242400 +/* -------------------------------------------------- + * Errata Workaround for Neoverse N2 Erratum 2280757. + * This applies to revision r0p0 of Neoverse N2. it is still open. + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x1, x17 + * -------------------------------------------------- + */ +func errata_n2_2280757_wa + /* Check revision. */ + mov x17, x30 + bl check_errata_2280757 + cbz x0, 1f + + /* Apply instruction patching sequence */ + mrs x1, NEOVERSE_N2_CPUACTLR_EL1 + orr x1, x1, NEOVERSE_N2_CPUACTLR_EL1_BIT_22 + msr NEOVERSE_N2_CPUACTLR_EL1, x1 +1: + ret x17 +endfunc errata_n2_2280757_wa + +func check_errata_2280757 + /* Applies to r0p0 */ + mov x1, #0x00 + b cpu_rev_var_ls +endfunc check_errata_2280757 + /* ------------------------------------------- * The CPU Ops reset function for Neoverse N2. * ------------------------------------------- @@ -366,6 +394,11 @@ func neoverse_n2_reset_func bl errata_n2_2242400_wa #endif +#if ERRATA_N2_2280757 + mov x0, x18 + bl errata_n2_2280757_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, cptr_el3 @@ -435,6 +468,7 @@ func neoverse_n2_errata_report report_errata ERRATA_N2_2242415, neoverse_n2, 2242415 report_errata ERRATA_N2_2138958, neoverse_n2, 2138958 report_errata ERRATA_N2_2242400, neoverse_n2, 2242400 + report_errata ERRATA_N2_2280757, neoverse_n2, 2280757 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index f0da13919..cdb978b09 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -473,6 +473,10 @@ ERRATA_N2_2138958 ?=0 # to revision r0p0 of the Neoverse N2 cpu and is still open. ERRATA_N2_2242400 ?=0 +# Flag to apply erratum 2280757 workaround during reset. This erratum applies +# to revision r0p0 of the Neoverse N2 cpu and is still open. +ERRATA_N2_2280757 ?=0 + # Flag to apply erratum 2055002 workaround during reset. This erratum applies # to revision r1p0, r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_2055002 ?=0 @@ -886,6 +890,10 @@ $(eval $(call add_define,ERRATA_N2_2138958)) $(eval $(call assert_boolean,ERRATA_N2_2242400)) $(eval $(call add_define,ERRATA_N2_2242400)) +# Process ERRATA_N2_2280757 flag +$(eval $(call assert_boolean,ERRATA_N2_2280757)) +$(eval $(call add_define,ERRATA_N2_2280757)) + # Process ERRATA_A710_2055002 flag $(eval $(call assert_boolean,ERRATA_A710_2055002)) $(eval $(call add_define,ERRATA_A710_2055002)) -- cgit v1.2.3 From 025f5ef201a39ba7285f368139e690bbd7a44653 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 4 Nov 2021 14:39:28 +0100 Subject: fix(drivers/usb): remove unnecessary cast Remove the unnecessary cast on the result of function which already return the correct type. Signed-off-by: Patrick Delaunay Change-Id: Ie21f7e78a880d30d1f31e32b3d2c3fb09489d65b --- drivers/usb/usb_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c index ce02d4fc4..7fcb39b15 100644 --- a/drivers/usb/usb_device.c +++ b/drivers/usb/usb_device.c @@ -73,7 +73,7 @@ static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req break; case USB_DESC_TYPE_CONFIGURATION: - pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); + pbuf = pdev->desc->get_config_desc(&len); pbuf[1] = USB_DESC_TYPE_CONFIGURATION; break; @@ -112,11 +112,11 @@ static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req break; case USB_DESC_TYPE_DEVICE_QUALIFIER: - pbuf = (uint8_t *)pdev->desc->get_device_qualifier_desc(&len); + pbuf = pdev->desc->get_device_qualifier_desc(&len); break; case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: - pbuf = (uint8_t *)pdev->desc->get_config_desc(&len); + pbuf = pdev->desc->get_config_desc(&len); pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; break; -- cgit v1.2.3 From 216c1223c2c65bd1c119a28b9406f70a9ee7b063 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 4 Nov 2021 15:13:33 +0100 Subject: fix(drivers/usb): add a optional ops get_other_speed_config_desc Correctly handle USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION request in USB driver and support a different result than USB_DESC_TYPE_CONFIGURATION with the new optional ops get_other_speed_config_desc(). The support of this descriptor is optionnal and is only required when high-speed capable device which can operate at its other possible speed. This patch allows to remove the pbuf update in usb_core_get_desc() and solves an issue on USB re-enumeration on STM32MP15 platform as the result of get_config_desc() is a const array. This issue is not see on normal use-case, as the USB enumeration is only done in ROM code and TF-A reuse the same USB descritors. Signed-off-by: Patrick Delaunay Change-Id: I8edcc1e45065ab4e45d48f4bc37b49120674fdb0 --- drivers/usb/usb_device.c | 8 +++++--- include/drivers/usb_device.h | 2 ++ plat/st/stm32mp1/stm32mp1_usb_dfu.c | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/usb_device.c b/drivers/usb/usb_device.c index 7fcb39b15..7dd3f6069 100644 --- a/drivers/usb/usb_device.c +++ b/drivers/usb/usb_device.c @@ -74,7 +74,6 @@ static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req case USB_DESC_TYPE_CONFIGURATION: pbuf = pdev->desc->get_config_desc(&len); - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; break; case USB_DESC_TYPE_STRING: @@ -116,8 +115,11 @@ static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req break; case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: - pbuf = pdev->desc->get_config_desc(&len); - pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + if (pdev->desc->get_other_speed_config_desc == NULL) { + usb_core_ctl_error(pdev); + return; + } + pbuf = pdev->desc->get_other_speed_config_desc(&len); break; default: diff --git a/include/drivers/usb_device.h b/include/drivers/usb_device.h index e21e3155d..8fdb6ae13 100644 --- a/include/drivers/usb_device.h +++ b/include/drivers/usb_device.h @@ -166,6 +166,8 @@ struct usb_desc { uint8_t *(*get_usr_desc)(uint8_t index, uint16_t *length); uint8_t *(*get_config_desc)(uint16_t *length); uint8_t *(*get_device_qualifier_desc)(uint16_t *length); + /* optional: high speed capable device operating at its other speed */ + uint8_t *(*get_other_speed_config_desc)(uint16_t *length); }; /* USB Device handle structure */ diff --git a/plat/st/stm32mp1/stm32mp1_usb_dfu.c b/plat/st/stm32mp1/stm32mp1_usb_dfu.c index 051d43532..70fbba6db 100644 --- a/plat/st/stm32mp1/stm32mp1_usb_dfu.c +++ b/plat/st/stm32mp1/stm32mp1_usb_dfu.c @@ -338,6 +338,8 @@ static const struct usb_desc dfu_desc = { .get_usr_desc = stm32mp1_get_usr_desc, .get_config_desc = stm32mp1_get_config_desc, .get_device_qualifier_desc = stm32mp1_get_qualifier_desc, + /* only HS is supported, as ROM code */ + .get_other_speed_config_desc = NULL, }; static struct usb_handle usb_core_handle; -- cgit v1.2.3 From 77612b90acaffc82cea712f4a431c727bbb968ec Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Mon, 11 Oct 2021 14:38:46 +0100 Subject: fix(gpt_rme): add necessary barriers and remove cache clean This patch adds necessary barriers after GPT entries are modified so that the writes are observed correctly by the GPC hardware. The shareability of GPC fetches are changed from OSH to ISH so that they align with the shareability of MMU attributes for the region. Thus by adding a dsbishst() between the GPT L1 entry write as part of granule migration at runtime, we can now remove the clean cache maintenance operation (CMO) for that region. Signed-off-by: Soby Mathew Signed-off-by: Robert Wakim Change-Id: Ib9e405b106f0db95c7fbdb26773c0ed41663a5b4 --- lib/gpt_rme/gpt_rme.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c index 1f90e64cf..6d1ff4dac 100644 --- a/lib/gpt_rme/gpt_rme.c +++ b/lib/gpt_rme/gpt_rme.c @@ -708,8 +708,12 @@ int gpt_enable(void) /* GPCCR_EL3.PGS */ gpccr_el3 |= SET_GPCCR_PGS(gpt_config.pgs); - /* Set shareability attribute to Outher Shareable */ - gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_OS); + /* + * Since EL3 maps the L1 region as Inner shareable, use the same + * shareability attribute for GPC as well so that + * GPC fetches are visible to PEs + */ + gpccr_el3 |= SET_GPCCR_SH(GPCCR_SH_IS); /* Outer and Inner cacheability set to Normal memory, WB, RA, WA. */ gpccr_el3 |= SET_GPCCR_ORGN(GPCCR_ORGN_WB_RA_WA); @@ -720,6 +724,7 @@ int gpt_enable(void) /* TODO: Configure GPCCR_EL3_GPCP for Fault control. */ write_gpccr_el3(gpccr_el3); + isb(); tlbipaallos(); dsb(); isb(); @@ -759,7 +764,7 @@ int gpt_init_l0_tables(unsigned int pps, uintptr_t l0_mem_base, int ret; uint64_t gpt_desc; - /* Ensure that MMU and caches are enabled. */ + /* Ensure that MMU and Data caches are enabled. */ assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); /* Validate other parameters. */ @@ -814,7 +819,7 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base, int ret; int l1_gpt_cnt; - /* Ensure that MMU and caches are enabled. */ + /* Ensure that MMU and Data caches are enabled. */ assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); /* PGS is needed for gpt_validate_pas_mappings so check it now. */ @@ -888,6 +893,9 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base, /* Make sure that all the entries are written to the memory. */ dsbishst(); + tlbipaallos(); + dsb(); + isb(); return 0; } @@ -907,7 +915,7 @@ int gpt_runtime_init(void) { u_register_t reg; - /* Ensure that MMU and caches are enabled. */ + /* Ensure that MMU and Data caches are enabled. */ assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); /* Ensure GPC are already enabled. */ @@ -1028,6 +1036,9 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, /* Ensure that the tables have been set up before taking requests. */ assert(gpt_config.plat_gpt_l0_base != 0U); + /* Ensure that MMU and data caches are enabled. */ + assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U); + /* Check for address range overflow. */ if ((ULONG_MAX - base) < size) { VERBOSE("[GPT] Transition request address overflow!\n"); @@ -1093,18 +1104,18 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, gpt_l1_desc |= ((uint64_t)target_pas << gpi_shift); gpt_l1_addr[idx] = gpt_l1_desc; - /* Ensure that the write operation happens before the unlock. */ - dmbishst(); + /* Ensure that the write operation will be observed by GPC */ + dsbishst(); /* Unlock access to the L1 tables. */ spin_unlock(&gpt_lock); - /* Cache maintenance. */ - clean_dcache_range((uintptr_t)&gpt_l1_addr[idx], - sizeof(uint64_t)); gpt_tlbi_by_pa(base, GPT_PGS_ACTUAL_SIZE(gpt_config.p)); dsbishst(); - + /* + * The isb() will be done as part of context + * synchronization when returning to lower EL + */ VERBOSE("[GPT] Granule 0x%llx, GPI 0x%x->0x%x\n", base, gpi, target_pas); -- cgit v1.2.3 From d39db2695ba626b9c0ee38652fe160b4e84b15d9 Mon Sep 17 00:00:00 2001 From: Ming Huang Date: Thu, 9 Sep 2021 17:42:27 +0800 Subject: fix(sdei): fix assert while kdump issue Assert condition: 1 Register secure timer(ppi=29) for sdei nmi watchdog; 2 kernel panic and then kdump; While kdump, kernel mask all cores sdei, secure timer trigger and go to handle_masked_trigger() and assert here: assert(se->affinity == my_mpidr); As kernel register with flag=0, mpidr=0 and TF-A set flag to SDEI_REGF_RM_PE but leave mpidr=0. So set mpidr to fix his assert issue. Signed-off-by: Ming Huang Change-Id: Ia9182f40bde94fb004b46e2a72b186eb0ef05166 --- services/std_svc/sdei/sdei_main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c index 4ceaae891..7c85c2380 100644 --- a/services/std_svc/sdei/sdei_main.c +++ b/services/std_svc/sdei/sdei_main.c @@ -359,8 +359,20 @@ static int64_t sdei_event_register(int ev_num, return SDEI_EINVAL; /* Private events always target the PE */ - if (is_event_private(map)) + if (is_event_private(map)) { + /* + * SDEI internally handles private events in the same manner + * as public events with routing mode=RM_PE, since the routing + * mode flag and affinity fields are not used when registering + * a private event, set them here. + */ flags = SDEI_REGF_RM_PE; + /* + * Kernel may pass 0 as mpidr, as we set flags to + * SDEI_REGF_RM_PE, so set mpidr also. + */ + mpidr = read_mpidr_el1(); + } se = get_event_entry(map); -- cgit v1.2.3 From 8d26029168fe70a86de524ed68c56e8666823714 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Tue, 2 Nov 2021 15:06:01 +0100 Subject: fix(fdts stm32mp1): correct copyright dates Add 2021 year in the file header Copyright line. Change-Id: I09f7bef1f746c429ff308286169354e58648a1cd Signed-off-by: Yann Gautier --- fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi | 2 +- fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi | 2 +- fdts/stm32mp15-pinctrl.dtsi | 2 +- fdts/stm32mp151.dtsi | 2 +- fdts/stm32mp157c-ed1.dts | 2 +- fdts/stm32mp157c-ev1.dts | 2 +- fdts/stm32mp157c-lxa-mc1.dts | 2 +- fdts/stm32mp15xx-dkx.dtsi | 2 +- fdts/stm32mp15xxaa-pinctrl.dtsi | 2 +- fdts/stm32mp15xxab-pinctrl.dtsi | 2 +- fdts/stm32mp15xxac-pinctrl.dtsi | 2 +- fdts/stm32mp15xxad-pinctrl.dtsi | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi index 6ca6293d4..c6d6434a9 100644 --- a/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-1x4Gb-1066-binG.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved */ /* diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi index 548f69a19..9614ab4c8 100644 --- a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi +++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* - * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * Copyright (c) 2018-2021, STMicroelectronics - All Rights Reserved */ /* diff --git a/fdts/stm32mp15-pinctrl.dtsi b/fdts/stm32mp15-pinctrl.dtsi index e8e6b9f3f..d74dc2b09 100644 --- a/fdts/stm32mp15-pinctrl.dtsi +++ b/fdts/stm32mp15-pinctrl.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017 - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * Author: Ludovic Barre for STMicroelectronics. */ #include diff --git a/fdts/stm32mp151.dtsi b/fdts/stm32mp151.dtsi index 3beabbbb4..ca93f0c35 100644 --- a/fdts/stm32mp151.dtsi +++ b/fdts/stm32mp151.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017 - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * Author: Ludovic Barre for STMicroelectronics. */ #include diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts index a09c66afa..11e0a6111 100644 --- a/fdts/stm32mp157c-ed1.dts +++ b/fdts/stm32mp157c-ed1.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * Author: Ludovic Barre for STMicroelectronics. */ /dts-v1/; diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts index 4937514fb..02840a2e5 100644 --- a/fdts/stm32mp157c-ev1.dts +++ b/fdts/stm32mp157c-ev1.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved + * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved * Author: Ludovic Barre for STMicroelectronics. */ /dts-v1/; diff --git a/fdts/stm32mp157c-lxa-mc1.dts b/fdts/stm32mp157c-lxa-mc1.dts index 31f138239..6f677123a 100644 --- a/fdts/stm32mp157c-lxa-mc1.dts +++ b/fdts/stm32mp157c-lxa-mc1.dts @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */ /* - * Copyright (C) 2020 STMicroelectronics - All Rights Reserved + * Copyright (c) 2020-2021, STMicroelectronics - All Rights Reserved * Copyright (C) 2020 Ahmad Fatoum, Pengutronix */ diff --git a/fdts/stm32mp15xx-dkx.dtsi b/fdts/stm32mp15xx-dkx.dtsi index 69b48285a..9cc5368d8 100644 --- a/fdts/stm32mp15xx-dkx.dtsi +++ b/fdts/stm32mp15xx-dkx.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * Author: Alexandre Torgue for STMicroelectronics. */ diff --git a/fdts/stm32mp15xxaa-pinctrl.dtsi b/fdts/stm32mp15xxaa-pinctrl.dtsi index 04f7a43ad..f1d540abe 100644 --- a/fdts/stm32mp15xxaa-pinctrl.dtsi +++ b/fdts/stm32mp15xxaa-pinctrl.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * Author: Alexandre Torgue for STMicroelectronics. */ diff --git a/fdts/stm32mp15xxab-pinctrl.dtsi b/fdts/stm32mp15xxab-pinctrl.dtsi index 328dad140..b58c7e2bf 100644 --- a/fdts/stm32mp15xxab-pinctrl.dtsi +++ b/fdts/stm32mp15xxab-pinctrl.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * Author: Alexandre Torgue for STMicroelectronics. */ diff --git a/fdts/stm32mp15xxac-pinctrl.dtsi b/fdts/stm32mp15xxac-pinctrl.dtsi index 7eaa245f4..11e7e0344 100644 --- a/fdts/stm32mp15xxac-pinctrl.dtsi +++ b/fdts/stm32mp15xxac-pinctrl.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * Author: Alexandre Torgue for STMicroelectronics. */ diff --git a/fdts/stm32mp15xxad-pinctrl.dtsi b/fdts/stm32mp15xxad-pinctrl.dtsi index b63e207de..52806d61c 100644 --- a/fdts/stm32mp15xxad-pinctrl.dtsi +++ b/fdts/stm32mp15xxad-pinctrl.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* - * Copyright (C) STMicroelectronics 2019 - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * Author: Alexandre Torgue for STMicroelectronics. */ -- cgit v1.2.3 From 325376eb818b95ade63a58476cf2e75c00578aa0 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Fri, 29 Oct 2021 17:04:17 +0200 Subject: refactor(stm32mp1): use fconf.mk Update STM32MP1 platform.mk file to include fconf.mk. Change-Id: Idc623a832b4cdf9486835fc612803015f4f1a5f5 Signed-off-by: Yann Gautier --- plat/st/stm32mp1/platform.mk | 12 ++++++++---- plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk | 4 ++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index c8c2e5f0b..badc926c0 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -159,15 +159,17 @@ $(eval $(call add_defines,\ PLAT_INCLUDES := -Iplat/st/common/include/ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ +ifeq (${STM32MP_USE_STM32IMAGE},1) include common/fdt_wrappers.mk +else +include lib/fconf/fconf.mk +endif include lib/libfdt/libfdt.mk PLAT_BL_COMMON_SOURCES := common/uuid.c \ plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c -PLAT_BL_COMMON_SOURCES += ${FDT_WRAPPERS_SOURCES} - PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S ifneq (${ENABLE_STACK_PROTECTOR},0) @@ -199,14 +201,16 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \ plat/st/stm32mp1/stm32mp1_syscfg.c ifneq (${STM32MP_USE_STM32IMAGE},1) +BL2_SOURCES += ${FCONF_SOURCES} ${FCONF_DYN_SOURCES} + BL2_SOURCES += drivers/io/io_fip.c \ - lib/fconf/fconf.c \ - lib/fconf/fconf_dyn_cfg_getter.c \ plat/st/common/bl2_io_storage.c \ plat/st/common/stm32mp_fconf_io.c \ plat/st/stm32mp1/plat_bl2_mem_params_desc.c \ plat/st/stm32mp1/stm32mp1_fconf_firewall.c else +BL2_SOURCES += ${FDT_WRAPPERS_SOURCES} + BL2_SOURCES += drivers/io/io_dummy.c \ drivers/st/io/io_stm32image.c \ plat/st/common/bl2_stm32_io_storage.c \ diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk index 4d4820afa..239b60af4 100644 --- a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk +++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk @@ -15,6 +15,10 @@ BL32_SOURCES += drivers/st/etzpc/etzpc.c \ plat/st/stm32mp1/stm32mp1_shared_resources.c \ plat/st/stm32mp1/stm32mp1_topology.c +# FDT wrappers +include common/fdt_wrappers.mk +BL32_SOURCES += ${FDT_WRAPPERS_SOURCES} + # Generic GIC v2 include drivers/arm/gic/v2/gicv2.mk -- cgit v1.2.3 From 96b71eb9597efbf4857216cac1caeefc9e8bbf3e Mon Sep 17 00:00:00 2001 From: J-Alves Date: Mon, 1 Nov 2021 16:52:46 +0000 Subject: feat(ff-a): feature retrieval through FFA_FEATURES call Updated FFA_FEATURES according to FF-A v1.1 in SPMC can also be used to retrieve feature information, and should now accept other arguments than just FF-A call IDs. Signed-off-by: J-Alves Change-Id: I02cc24a31ab3092ec1ce6fed1a9649ffe7136782 --- services/std_svc/spmd/spmd_main.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6de5feb0e..a9ff459da 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -489,15 +489,6 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, * forward to SPM Core which will handle it if implemented. */ - /* - * Check if x1 holds a valid FFA fid. This is an - * optimization. - */ - if (!is_ffa_fid(x1)) { - return spmd_ffa_error_return(handle, - FFA_ERROR_NOT_SUPPORTED); - } - /* Forward SMC from Normal world to the SPM Core */ if (!secure_origin) { return spmd_smc_forward(smc_fid, secure_origin, -- cgit v1.2.3 From 1ea9190c6a4d2299c6dc19adc0bbe93d4f051eff Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 2 Sep 2021 17:53:30 -0500 Subject: fix(errata): workaround for Cortex A78 erratum 2242635 Cortex A78 erratum 2242635 is a Cat B erratum present in the A78 Core. It applies to revisions r1p0, r1p1, r1p2, and is still open. The issue is also present in r0p0 but there is no workaround for this revision. SDEN can be found here: https://developer.arm.com/documentation/SDEN1401784 Signed-off-by: John Powell Change-Id: Ieca024254cabbc683ff13a70f3aeb8f2f3c5ce07 --- docs/design/cpu-specific-build-macros.rst | 4 +++ lib/cpus/aarch64/cortex_a78.S | 42 +++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 45 ++++++++++++++++++------------- 3 files changed, 73 insertions(+), 18 deletions(-) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index b5ec36318..1d4f67ab7 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -288,6 +288,10 @@ For Cortex-A78, the following errata build flags are defined : CPU. This needs to be enabled for revisions r0p0, r1p0, r1p1, and r1p2. It is still open. +- ``ERRATA_A78_2242635``: This applies errata 2242635 workaround to Cortex-A78 + CPU. This needs to be enabled for revisions r1p0, r1p1, and r1p2. The issue + is present in r0p0 but there is no workaround. It is still open. + For Cortex-A78 AE, the following errata build flags are defined : - ``ERRATA_A78_AE_1941500`` : This applies errata 1941500 workaround to Cortex-A78 diff --git a/lib/cpus/aarch64/cortex_a78.S b/lib/cpus/aarch64/cortex_a78.S index 4e8a228ed..a1288bab1 100644 --- a/lib/cpus/aarch64/cortex_a78.S +++ b/lib/cpus/aarch64/cortex_a78.S @@ -227,6 +227,42 @@ func check_errata_2132060 b cpu_rev_var_ls endfunc check_errata_2132060 +/* -------------------------------------------------------------------- + * Errata Workaround for A78 Erratum 2242635. + * This applies to revisions r1p0, r1p1, and r1p2 of the Cortex A78 + * processor and is still open. + * The issue also exists in r0p0 but there is no fix in that revision. + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------------------------- + */ +func errata_a78_2242635_wa + /* Compare x0 against revisions r1p0 - r1p2 */ + mov x17, x30 + bl check_errata_2242635 + cbz x0, 1f + + ldr x0, =0x5 + msr S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */ + ldr x0, =0x10F600E000 + msr S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */ + ldr x0, =0x10FF80E000 + msr S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */ + ldr x0, =0x80000000003FF + msr S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */ + + isb +1: + ret x17 +endfunc errata_a78_2242635_wa + +func check_errata_2242635 + /* Applies to revisions r1p0 through r1p2. */ + mov x1, #CPU_REV(1, 0) + mov x2, #CPU_REV(1, 2) + b cpu_rev_var_range +endfunc check_errata_2242635 + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A78 * ------------------------------------------------- @@ -266,6 +302,11 @@ func cortex_a78_reset_func bl errata_a78_2132060_wa #endif +#if ERRATA_A78_2242635 + mov x0, x18 + bl errata_a78_2242635_wa +#endif + #if ENABLE_AMU /* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */ mrs x0, actlr_el3 @@ -326,6 +367,7 @@ func cortex_a78_errata_report report_errata ERRATA_A78_1821534, cortex_a78, 1821534 report_errata ERRATA_A78_1952683, cortex_a78, 1952683 report_errata ERRATA_A78_2132060, cortex_a78, 2132060 + report_errata ERRATA_A78_2242635, cortex_a78, 2242635 ldp x8, x30, [sp], #16 ret diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index cdb978b09..6a514ef77 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -311,25 +311,30 @@ ERRATA_A78_1941498 ?=0 # well but there is no workaround for that revision. ERRATA_A78_1951500 ?=0 -# Flag to apply erratum 1941500 workaround during reset. This erratum applies -# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. -ERRATA_A78_AE_1941500 ?=0 - -# Flag to apply erratum 1951502 workaround during reset. This erratum applies -# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. -ERRATA_A78_AE_1951502 ?=0 - # Flag to apply erratum 1821534 workaround during reset. This erratum applies # to revisions r0p0 and r1p0 of the A78 cpu. ERRATA_A78_1821534 ?=0 # Flag to apply erratum 1952683 workaround during reset. This erratum applies # to revision r0p0 of the A78 cpu and was fixed in the revision r1p0. -ERRATA_A78_1952683 ?=0 +ERRATA_A78_1952683 ?=0 # Flag to apply erratum 2132060 workaround during reset. This erratum applies # to revisions r0p0, r1p0, r1p1, and r1p2 of the A78 cpu. It is still open. -ERRATA_A78_2132060 ?=0 +ERRATA_A78_2132060 ?=0 + +# Flag to apply erratum 2242635 workaround during reset. This erratum applies +# to revisions r1p0, r1p1, and r1p2 of the A78 cpu and is open. The issue is +# present in r0p0 as well but there is no workaround for that revision. +ERRATA_A78_2242635 ?=0 + +# Flag to apply erratum 1941500 workaround during reset. This erratum applies +# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. +ERRATA_A78_AE_1941500 ?=0 + +# Flag to apply erratum 1951502 workaround during reset. This erratum applies +# to revisions r0p0 and r0p1 of the A78 AE cpu. It is still open. +ERRATA_A78_AE_1951502 ?=0 # Flag to apply T32 CLREX workaround during reset. This erratum applies # only to r0p0 and r1p0 of the Neoverse N1 cpu. @@ -730,14 +735,6 @@ $(eval $(call add_define,ERRATA_A78_1941498)) $(eval $(call assert_boolean,ERRATA_A78_1951500)) $(eval $(call add_define,ERRATA_A78_1951500)) -# Process ERRATA_A78_AE_1941500 flag -$(eval $(call assert_boolean,ERRATA_A78_AE_1941500)) -$(eval $(call add_define,ERRATA_A78_AE_1941500)) - -# Process ERRATA_A78_AE_1951502 flag -$(eval $(call assert_boolean,ERRATA_A78_AE_1951502)) -$(eval $(call add_define,ERRATA_A78_AE_1951502)) - # Process ERRATA_A78_1821534 flag $(eval $(call assert_boolean,ERRATA_A78_1821534)) $(eval $(call add_define,ERRATA_A78_1821534)) @@ -750,6 +747,18 @@ $(eval $(call add_define,ERRATA_A78_1952683)) $(eval $(call assert_boolean,ERRATA_A78_2132060)) $(eval $(call add_define,ERRATA_A78_2132060)) +# Process ERRATA_A78_2242635 flag +$(eval $(call assert_boolean,ERRATA_A78_2242635)) +$(eval $(call add_define,ERRATA_A78_2242635)) + +# Process ERRATA_A78_AE_1941500 flag +$(eval $(call assert_boolean,ERRATA_A78_AE_1941500)) +$(eval $(call add_define,ERRATA_A78_AE_1941500)) + +# Process ERRATA_A78_AE_1951502 flag +$(eval $(call assert_boolean,ERRATA_A78_AE_1951502)) +$(eval $(call add_define,ERRATA_A78_AE_1951502)) + # Process ERRATA_N1_1043202 flag $(eval $(call assert_boolean,ERRATA_N1_1043202)) $(eval $(call add_define,ERRATA_N1_1043202)) -- cgit v1.2.3 From aeea04d44d5b8be8843adb31b54529139b4b20a9 Mon Sep 17 00:00:00 2001 From: Raghu Krishnamurthy Date: Sun, 17 Oct 2021 16:48:29 -0700 Subject: docs(spm): document s-el0 partition support This patch adds a brief description of S-EL0 partition support in the SPMC using ARMv8.1 FEAT_VHE. Signed-off-by: Raghu Krishnamurthy Change-Id: Ie079265476604f62d5f2a66684f01341000969d0 --- docs/components/secure-partition-manager.rst | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index fa51fe026..89fea9ae1 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -919,6 +919,36 @@ streams. Fault handling, Performance Monitor Extensions, Event Handling, MPAM. - No support for independent peripheral devices. +S-EL0 Partition support +========================= +The SPMC (Hafnium) has limited capability to run S-EL0 FF-A partitions using +FEAT_VHE (mandatory with ARMv8.1 in non-secure state, and in secure world +with ARMv8.4 and FEAT_SEL2). + +S-EL0 partitions are useful for simple partitions that don't require full +Trusted OS functionality. It is also useful to reduce jitter and cycle +stealing from normal world since they are more lightweight than VMs. + +S-EL0 partitions are presented, loaded and initialized the same as S-EL1 VMs by +the SPMC. They are differentiated primarily by the 'exception-level' property +and the 'execution-ctx-count' property in the SP manifest. They are host apps +under the single EL2&0 Stage-1 translation regime controlled by the SPMC and +call into the SPMC through SVCs as opposed to HVCs and SMCs. These partitions +can use FF-A defined services (FFA_MEM_PERM_*) to update or change permissions +for memory regions. + +S-EL0 partitions are required by the FF-A specification to be UP endpoints, +capable of migrating, and the SPMC enforces this requirement. The SPMC allows +a S-EL0 partition to accept a direct message from secure world and normal world, +and generate direct responses to them. + +Memory sharing between and with S-EL0 partitions is supported. +Indirect messaging, Interrupt handling and Notifications are not supported with +S-EL0 partitions and is work in progress, planned for future releases. +All S-EL0 partitions must use AArch64. AArch32 S-EL0 partitions are not +supported. + + References ========== -- cgit v1.2.3 From 4c8fe6b17fa994a630b2a30f8666df103f2e370d Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 2 Sep 2021 18:29:17 -0500 Subject: fix(errata): workaround for Neoverse V1 erratum 2216392 Neoverse V1 erratum 2216392 is a Cat B erratum present in the V1 core. It applies to revisions r1p0 and r1p1 and is still open. The issue is also present in r0p0 but there is no workaround in that revision. SDEN can be found here: https://developer.arm.com/documentation/SDEN1401781 Signed-off-by: John Powell Change-Id: Ic2f90d79c75e8ffef01aac81eddf1bfd8b7164ab --- docs/design/cpu-specific-build-macros.rst | 5 ++++ lib/cpus/aarch64/neoverse_v1.S | 43 +++++++++++++++++++++++++++++++ lib/cpus/cpu-ops.mk | 9 +++++++ 3 files changed, 57 insertions(+) diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst index 1d4f67ab7..9d0dd5e2f 100644 --- a/docs/design/cpu-specific-build-macros.rst +++ b/docs/design/cpu-specific-build-macros.rst @@ -378,6 +378,11 @@ For Neoverse V1, the following errata build flags are defined : CPU. This needs to be enabled for revisions r0p0, r1p0, and r1p1 of the CPU. It is still open. +- ``ERRATA_V1_2216392``: This applies errata 2216392 workaround to Neoverse-V1 + CPU. This needs to be enabled for revisions r1p0 and r1p1 of the CPU, the + issue is present in r0p0 as well but there is no workaround for that + revision. It is still open. + For Cortex-A710, the following errata build flags are defined : - ``ERRATA_A710_1987031``: This applies errata 1987031 workaround to diff --git a/lib/cpus/aarch64/neoverse_v1.S b/lib/cpus/aarch64/neoverse_v1.S index 200f67de3..62a7a30cd 100644 --- a/lib/cpus/aarch64/neoverse_v1.S +++ b/lib/cpus/aarch64/neoverse_v1.S @@ -288,6 +288,43 @@ func check_errata_2108267 b cpu_rev_var_ls endfunc check_errata_2108267 + /* -------------------------------------------------- + * Errata Workaround for Neoverse V1 Errata #2216392. + * This applies to revisions r1p0 and r1p1 and is + * still open. + * This issue is also present in r0p0 but there is no + * workaround in that revision. + * x0: variant[4:7] and revision[0:3] of current cpu. + * Shall clobber: x0-x17 + * -------------------------------------------------- + */ +func errata_neoverse_v1_2216392_wa + /* Check workaround compatibility. */ + mov x17, x30 + bl check_errata_2216392 + cbz x0, 1f + + ldr x0, =0x5 + msr S3_6_c15_c8_0, x0 /* CPUPSELR_EL3 */ + ldr x0, =0x10F600E000 + msr S3_6_c15_c8_2, x0 /* CPUPOR_EL3 */ + ldr x0, =0x10FF80E000 + msr S3_6_c15_c8_3, x0 /* CPUPMR_EL3 */ + ldr x0, =0x80000000003FF + msr S3_6_c15_c8_1, x0 /* CPUPCR_EL3 */ + + isb +1: + ret x17 +endfunc errata_neoverse_v1_2216392_wa + +func check_errata_2216392 + /* Applies to revisions r1p0 and r1p1. */ + mov x1, #CPU_REV(1, 0) + mov x2, #CPU_REV(1, 1) + b cpu_rev_var_range +endfunc check_errata_2216392 + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- @@ -326,6 +363,7 @@ func neoverse_v1_errata_report report_errata ERRATA_V1_1966096, neoverse_v1, 1966096 report_errata ERRATA_V1_2139242, neoverse_v1, 2139242 report_errata ERRATA_V1_2108267, neoverse_v1, 2108267 + report_errata ERRATA_V1_2216392, neoverse_v1, 2216392 ldp x8, x30, [sp], #16 ret @@ -379,6 +417,11 @@ func neoverse_v1_reset_func bl errata_neoverse_v1_2108267_wa #endif +#if ERRATA_V1_2216392 + mov x0, x18 + bl errata_neoverse_v1_2216392_wa +#endif + ret x19 endfunc neoverse_v1_reset_func diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index 6a514ef77..a5b8aae29 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -430,6 +430,11 @@ ERRATA_V1_2139242 ?=0 # to revisions r0p0, r1p0, and r1p1 of the Neoverse V1 cpu and is still open. ERRATA_V1_2108267 ?=0 +# Flag to apply erratum 2216392 workaround during reset. This erratum applies +# to revisions r1p0 and r1p1 of the Neoverse V1 cpu and is still open. This +# issue exists in r0p0 as well but there is no workaround for that revision. +ERRATA_V1_2216392 ?=0 + # Flag to apply erratum 1987031 workaround during reset. This erratum applies # to revisions r0p0, r1p0 and r2p0 of the Cortex-A710 cpu and is still open. ERRATA_A710_1987031 ?=0 @@ -851,6 +856,10 @@ $(eval $(call add_define,ERRATA_V1_2139242)) $(eval $(call assert_boolean,ERRATA_V1_2108267)) $(eval $(call add_define,ERRATA_V1_2108267)) +# Process ERRATA_V1_2216392 flag +$(eval $(call assert_boolean,ERRATA_V1_2216392)) +$(eval $(call add_define,ERRATA_V1_2216392)) + # Process ERRATA_A710_1987031 flag $(eval $(call assert_boolean,ERRATA_A710_1987031)) $(eval $(call add_define,ERRATA_A710_1987031)) -- cgit v1.2.3 From a125c556230501ee0f5ec9f8b0b721625d484a41 Mon Sep 17 00:00:00 2001 From: Javier Almansa Sobrino Date: Mon, 5 Jul 2021 12:04:22 +0100 Subject: feat(measured boot): add documentation to build and run PoC Add documentation to build and run a PoC based on the OP-TEE toolkit to show how TF-A Measured Boot can interact with a third party (f)TPM service. Signed-off-by: Javier Almansa Sobrino Change-Id: I11ac99c4ff54ea52aba0731aa7f707d7cd0c4216 --- docs/design_documents/index.rst | 1 + docs/design_documents/measured_boot_poc.rst | 507 ++++++++++++++++++++++++++++ 2 files changed, 508 insertions(+) create mode 100644 docs/design_documents/measured_boot_poc.rst diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst index 187510a64..c82d2eeb3 100644 --- a/docs/design_documents/index.rst +++ b/docs/design_documents/index.rst @@ -7,6 +7,7 @@ Design Documents :numbered: cmake_framework + measured_boot_poc -------------- diff --git a/docs/design_documents/measured_boot_poc.rst b/docs/design_documents/measured_boot_poc.rst new file mode 100644 index 000000000..3ae539b5b --- /dev/null +++ b/docs/design_documents/measured_boot_poc.rst @@ -0,0 +1,507 @@ +Interaction between Measured Boot and an fTPM (PoC) +=================================================== + +Measured Boot is the process of cryptographically measuring the code and +critical data used at boot time, for example using a TPM, so that the +security state can be attested later. + +The current implementation of the driver included in Trusted Firmware-A +(TF-A) stores the measurements into a `TGC event log`_ in secure +memory. No other means of recording measurements (such as a discrete TPM) is +supported right now. + +The driver also provides mechanisms to pass the Event Log to normal world if +needed. + +This manual provides instructions to build a proof of concept (PoC) with the +sole intention of showing how Measured Boot can be used in conjunction with +a firmware TPM (fTPM) service implemented on top of OP-TEE. + +.. note:: + The instructions given in this document are meant to be used to build + a PoC to show how Measured Boot on TF-A can interact with a third + party (f)TPM service and they try to be as general as possible. Different + platforms might have different needs and configurations (e.g. different + SHA algorithms) and they might also use different types of TPM services + (or even a different type of service to provide the attestation) + and therefore the instuctions given here might not apply in such scenarios. + +Components +~~~~~~~~~~ + +The PoC is built on top of the `OP-TEE Toolkit`_, which has support to build +TF-A with support for Measured Boot enabled (and run it on a Foundation Model) +since commit cf56848. + +The aforementioned toolkit builds a set of images that contain all the components +needed to test that the Event Log was properly created. One of these images will +contain a third party fTPM service which in turn will be used to process the +Event Log. + +The reason to choose OP-TEE Toolkit to build our PoC around it is mostly +for convenience. As the fTPM service used is an OP-TEE TA, it was easy to add +build support for it to the toolkit and then build the PoC around it. + +The most relevant components installed in the image that are closely related to +Measured Boot/fTPM functionality are: + + - **OP-TEE**: As stated earlier, the fTPM service used in this PoC is built as an + OP-TEE TA and therefore we need to include the OP-TEE OS image. + Support to interfacing with Measured Boot was added to version 3.9.0 of + OP-TEE by implementing the ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` syscall, which + allows the former to pass a copy of the Event Log to any TA requesting it. + OP-TEE knows the location of the Event Log by reading the DTB bindings + received from TF-A. Visit :ref:`DTB binding for Event Log properties` + for more details on this. + + - **fTPM Service**: We use a third party fTPM service in order to validate + the Measured Boot functionality. The chosen fTPM service is a sample + implementation for Aarch32 architecture included on the `ms-tpm-20-ref`_ + reference implementation from Microsoft. The service was updated in order + to extend the Measured Boot Event Log at boot up and it uses the + aforementioned ``PTA_SYSTEM_GET_TPM_EVENT_LOG`` call to retrieve a copy + of the former. + + .. note:: + Arm does not provide an fTPM implementation. The fTPM service used here + is a third party one which has been updated to support Measured Boot + service as provided by TF-A. As such, it is beyond the scope of this + manual to test and verify the correctness of the output generated by the + fTPM service. + + - **TPM Kernel module**: In order to interact with the fTPM service, we need + a kernel module to forward the request from user space to the secure world. + + - `tpm2-tools`_: This is a set of tools that allow to interact with the + fTPM service. We use this in order to read the PCRs with the measurements. + +Building the PoC for the Arm FVP platform +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned before, this PoC is based on the OP-TEE Toolkit with some +extensions to enable Measured Boot and an fTPM service. Therefore, we can rely +on the instructions to build the original OP-TEE Toolkit. As a general rule, +the following steps should suffice: + +(1) Start by following the `Get and build the solution`_ instructions to build + the OP-TEE toolkit. On step 3, you need to get the manifest for FVP + platform from the main branch: + + .. code:: shell + + $ repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml + + Then proceed synching the repos as stated in step 3. Continue following + the instructions and stop before step 5. + +(2) Next you should obtain the `Armv8-A Foundation Platform (For Linux Hosts Only)`_. + The binary should be untar'ed to the root of the repo tree, i.e., like + this: ``/Foundation_Platformpkg``. In the end, after cloning + all source code, getting the toolchains and "installing" + Foundation_Platformpkg, you should have a folder structure that looks like + this: + + .. code:: shell + + $ ls -la + total 80 + drwxrwxr-x 20 tf-a_user tf-a_user 4096 Jul 1 12:16 . + drwxr-xr-x 23 tf-a_user tf-a_user 4096 Jul 1 10:40 .. + drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 10:45 build + drwxrwxr-x 16 tf-a_user tf-a_user 4096 Jul 1 12:16 buildroot + drwxrwxr-x 51 tf-a_user tf-a_user 4096 Jul 1 10:45 edk2 + drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 12:14 edk2-platforms + drwxr-xr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:52 Foundation_Platformpkg + drwxrwxr-x 17 tf-a_user tf-a_user 4096 Jul 2 10:40 grub + drwxrwxr-x 25 tf-a_user tf-a_user 4096 Jul 2 10:39 linux + drwxrwxr-x 15 tf-a_user tf-a_user 4096 Jul 1 10:45 mbedtls + drwxrwxr-x 6 tf-a_user tf-a_user 4096 Jul 1 10:45 ms-tpm-20-ref + drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_client + drwxrwxr-x 10 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_examples + drwxrwxr-x 12 tf-a_user tf-a_user 4096 Jul 1 12:13 optee_os + drwxrwxr-x 8 tf-a_user tf-a_user 4096 Jul 1 10:45 optee_test + drwxrwxr-x 7 tf-a_user tf-a_user 4096 Jul 1 10:45 .repo + drwxrwxr-x 4 tf-a_user tf-a_user 4096 Jul 1 12:12 toolchains + drwxrwxr-x 21 tf-a_user tf-a_user 4096 Jul 1 12:15 trusted-firmware-a + +(3) Now enter into ``ms-tpm-20-ref`` and get its dependencies: + + .. code:: shell + + $ cd ms-tpm-20-ref + $ git submodule init + $ git submodule update + Submodule path 'external/wolfssl': checked out '9c87f979a7f1d3a6d786b260653d566c1d31a1c4' + +(4) Now, you should be able to continue with step 5 in "`Get and build the solution`_" + instructions. In order to enable support for Measured Boot, you need to + set the ``MEASURED_BOOT`` build option: + + .. code:: shell + + $ MEASURED_BOOT=y make -j `nproc` + + .. note:: + The build process will likely take a long time. It is strongly recommended to + pass the ``-j`` option to make to run the process faster. + + After this step, you should be ready to run the image. + +Running and using the PoC on the Armv8-A Foundation AEM FVP +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With everything built, you can now run the image: + +.. code:: shell + + $ make run-only + +.. note:: + Using ``make run`` will build and run the image and it can be used instead + of simply ``make``. However, once the image is built, it is recommended to + use ``make run-only`` to avoid re-running all the building rules, which + would take time. + +When FVP is launched, two terminal windows will appear. ``FVP terminal_0`` +is the userspace terminal whereas ``FVP terminal_1`` is the counterpart for +the secure world (where TAs will print their logs, for instance). + +Log into the image shell with user ``root``, no password will be required. +Then we can issue the ``ftpm`` command, which is an alias that + +(1) loads the ftpm kernel module and + +(2) calls ``tpm2_pcrread``, which will access the fTPM service to read the + PCRs. + +When loading the ftpm kernel module, the fTPM TA is loaded into the secure +world. This TA then requests a copy of the Event Log generated during the +booting process so it can retrieve all the entries on the log and record them +first thing. + +.. note:: + For this PoC, nothing loaded after BL33 and NT_FW_CONFIG is recorded + in the Event Log. + +The secure world terminal should show the debug logs for the fTPM service, +including all the measurements available in the Event Log as they are being +processed: + +.. code:: shell + + M/TA: Preparing to extend the following TPM Event Log: + M/TA: TCG_EfiSpecIDEvent: + M/TA: PCRIndex : 0 + M/TA: EventType : 3 + M/TA: Digest : 00 + M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + M/TA: : 00 00 00 + M/TA: EventSize : 33 + M/TA: Signature : Spec ID Event03 + M/TA: PlatformClass : 0 + M/TA: SpecVersion : 2.0.2 + M/TA: UintnSize : 1 + M/TA: NumberOfAlgorithms : 1 + M/TA: DigestSizes : + M/TA: #0 AlgorithmId : SHA256 + M/TA: DigestSize : 32 + M/TA: VendorInfoSize : 0 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 3 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + M/TA: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + M/TA: EventSize : 17 + M/TA: Signature : StartupLocality + M/TA: StartupLocality : 0 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63 + M/TA: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5 + M/TA: EventSize : 5 + M/TA: Event : BL_2 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5 + M/TA: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c + M/TA: EventSize : 6 + M/TA: Event : BL_31 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2 + M/TA: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0 + M/TA: EventSize : 10 + M/TA: Event : HW_CONFIG + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a + M/TA: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0 + M/TA: EventSize : 14 + M/TA: Event : SOC_FW_CONFIG + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22 + M/TA: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75 + M/TA: EventSize : 6 + M/TA: Event : BL_32 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e + M/TA: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63 + M/TA: EventSize : 18 + M/TA: Event : BL32_EXTRA1_IMAGE + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25 + M/TA: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2 + M/TA: EventSize : 6 + M/TA: Event : BL_33 + M/TA: PCR_Event2: + M/TA: PCRIndex : 0 + M/TA: EventType : 1 + M/TA: Digests Count : 1 + M/TA: #0 AlgorithmId : SHA256 + M/TA: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6 + M/TA: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a + M/TA: EventSize : 13 + M/TA: Event : NT_FW_CONFIG + +These logs correspond to the measurements stored by TF-A during the measured +boot process and therefore, they should match the logs dumped by the former +during the boot up process. These can be seen on the terminal_0: + +.. code:: shell + + NOTICE: Booting Trusted Firmware + NOTICE: BL1: v2.5(release):v2.5 + NOTICE: BL1: Built : 10:41:20, Jul 2 2021 + NOTICE: BL1: Booting BL2 + NOTICE: BL2: v2.5(release):v2.5 + NOTICE: BL2: Built : 10:41:20, Jul 2 2021 + NOTICE: TCG_EfiSpecIDEvent: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 3 + NOTICE: Digest : 00 + NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: : 00 00 00 + NOTICE: EventSize : 33 + NOTICE: Signature : Spec ID Event03 + NOTICE: PlatformClass : 0 + NOTICE: SpecVersion : 2.0.2 + NOTICE: UintnSize : 1 + NOTICE: NumberOfAlgorithms : 1 + NOTICE: DigestSizes : + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: DigestSize : 32 + NOTICE: VendorInfoSize : 0 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 3 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + NOTICE: EventSize : 17 + NOTICE: Signature : StartupLocality + NOTICE: StartupLocality : 0 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 58 26 32 6e 64 45 64 da 45 de 35 db 96 fd ed 63 + NOTICE: : 2a 6a d4 0d aa 94 b0 b1 55 e4 72 e7 1f 0a e0 d5 + NOTICE: EventSize : 5 + NOTICE: Event : BL_2 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : cf f9 7d a3 5c 73 ac cb 7b a0 25 80 6a 6e 50 a5 + NOTICE: : 6b 2e d2 8c c9 36 92 7d 46 c5 b9 c3 a4 6c 51 7c + NOTICE: EventSize : 6 + NOTICE: Event : BL_31 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 23 b0 a3 5d 54 d9 43 1a 5c b9 89 63 1c da 06 c2 + NOTICE: : e5 de e7 7e 99 17 52 12 7d f7 45 ca 4f 4a 39 c0 + NOTICE: EventSize : 10 + NOTICE: Event : HW_CONFIG + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 4e e4 8e 5a e6 50 ed e0 b5 a3 54 8a 1f d6 0e 8a + NOTICE: : ea 0e 71 75 0e a4 3f 82 76 ce af cd 7c b0 91 e0 + NOTICE: EventSize : 14 + NOTICE: Event : SOC_FW_CONFIG + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 01 b0 80 47 a1 ce 86 cd df 89 d2 1f 2e fc 6c 22 + NOTICE: : f8 19 ec 6e 1e ec 73 ba 5a be d0 96 e3 5f 6d 75 + NOTICE: EventSize : 6 + NOTICE: Event : BL_32 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 5d c6 ef 35 5a 90 81 b4 37 e6 3b 52 da 92 ab 8e + NOTICE: : d9 6e 93 98 2d 40 87 96 1b 5a a7 ee f1 f4 40 63 + NOTICE: EventSize : 18 + NOTICE: Event : BL32_EXTRA1_IMAGE + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 39 b7 13 b9 93 db 32 2f 1b 48 30 eb 2c f2 5c 25 + NOTICE: : 00 0f 38 dc 8e c8 02 cd 79 f2 48 d2 2c 25 ab e2 + NOTICE: EventSize : 6 + NOTICE: Event : BL_33 + NOTICE: PCR_Event2: + NOTICE: PCRIndex : 0 + NOTICE: EventType : 1 + NOTICE: Digests Count : 1 + NOTICE: #0 AlgorithmId : SHA256 + NOTICE: Digest : 25 10 60 5d d4 bc 9d 82 7a 16 9f 8a cc 47 95 a6 + NOTICE: : fd ca a0 c1 2b c9 99 8f 51 20 ff c6 ed 74 68 5a + NOTICE: EventSize : 13 + NOTICE: Event : NT_FW_CONFIG + NOTICE: BL1: Booting BL31 + NOTICE: BL31: v2.5(release):v2.5 + NOTICE: BL31: Built : 10:41:20, Jul 2 2021 + +Following up with the fTPM startup process, we can see that all the +measurements in the Event Log are extended and recorded in the appropriate PCR: + +.. code:: shell + + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: TPM2_PCR_EXTEND_COMMAND returned value: + M/TA: ret_tag = 0x8002, size = 0x00000013, rc = 0x00000000 + M/TA: 9 Event logs processed + +After the fTPM TA is loaded, the call to ``insmod`` issued by the ``ftpm`` +alias to load the ftpm kernel module returns, and then the TPM PCRs are read +by means of ``tpm_pcrread`` command. Note that we are only interested in the +SHA256 logs here, as this is the algorithm we used on TF-A for the measurements +(see the field ``AlgorithmId`` on the logs above): + +.. code:: shell + + sha256: + 0 : 0xA6EB3A7417B8CFA9EBA2E7C22AD5A4C03CDB8F3FBDD7667F9C3EF2EA285A8C9F + 1 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 2 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 3 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 4 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 5 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 6 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 7 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 8 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 9 : 0x0000000000000000000000000000000000000000000000000000000000000000 + 10: 0x0000000000000000000000000000000000000000000000000000000000000000 + 11: 0x0000000000000000000000000000000000000000000000000000000000000000 + 12: 0x0000000000000000000000000000000000000000000000000000000000000000 + 13: 0x0000000000000000000000000000000000000000000000000000000000000000 + 14: 0x0000000000000000000000000000000000000000000000000000000000000000 + 15: 0x0000000000000000000000000000000000000000000000000000000000000000 + 16: 0x0000000000000000000000000000000000000000000000000000000000000000 + 17: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 18: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 19: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 20: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 21: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 22: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 23: 0x0000000000000000000000000000000000000000000000000000000000000000 + +In this PoC we are only interested in PCR0, which must be non-null. This is +because the boot process records all the images in this PCR (see field ``PCRIndex`` +on the Event Log above). The rest of the records must be 0 at this point. + +.. note:: + The fTPM service used has support only for 16 PCRs, therefore the content + of PCRs above 15 can be ignored. + +.. note:: + As stated earlier, Arm does not provide an fTPM implementation and therefore + we do not validate here if the content of PCR0 is correct or not. For this + PoC, we are only focused on the fact that the event log could be passed to a third + party fTPM and its records were properly extended. + +Fine-tuning the fTPM TA +~~~~~~~~~~~~~~~~~~~~~~~ + +As stated earlier, the OP-TEE Toolkit includes support to build a third party fTPM +service. The build options for this service are tailored for the PoC and defined in +the build environment variable ``FTPM_FLAGS`` (see ``/build/common.mk``) +but they can be modified if needed to better adapt it to a specific scenario. + +The most relevant options for Measured Boot support are: + + - **CFG_TA_DEBUG**: Enables debug logs in the Terminal_1 console. + - **CFG_TEE_TA_LOG_LEVEL**: Defines the log level used for the debug messages. + - **CFG_TA_MEASURED_BOOT**: Enables support for measured boot on the fTPM. + - **CFG_TA_EVENT_LOG_SIZE**: Defines the size, in bytes, of the larger event log that + the fTPM is able to store, as this buffer is allocated at build time. This must be at + least the same as the size of the event log generated by TF-A. If this build option + is not defined, the fTPM falls back to a default value of 1024 bytes, which is enough + for this PoC, so this variable is not defined in FTPM_FLAGS. + +-------------- + +*Copyright (c) 2021, Arm Limited. All rights reserved.* + +.. _OP-TEE Toolkit: https://github.com/OP-TEE/build +.. _ms-tpm-20-ref: https://github.com/microsoft/ms-tpm-20-ref +.. _Get and build the solution: https://optee.readthedocs.io/en/latest/building/gits/build.html#get-and-build-the-solution +.. _Armv8-A Foundation Platform (For Linux Hosts Only): https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models +.. _tpm2-tools: https://github.com/tpm2-software/tpm2-tools +.. _TGC event log: https://trustedcomputinggroup.org/resource/tcg-efi-platform-specification/ -- cgit v1.2.3 From 4ce3e99a336b74611349595ea7fd5ed0277c3eeb Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Tue, 25 Aug 2020 13:49:32 -0700 Subject: fix: libc: use long for 64-bit types on aarch64 Use long instead of long long on aarch64 for 64_t stdint types. Introduce inttypes.h to properly support printf format specifiers for fixed width types for such change. Change-Id: I0bca594687a996fde0a9702d7a383055b99f10a1 Signed-off-by: Scott Branden --- bl32/tsp/tsp_main.c | 6 ++- common/fdt_wrappers.c | 12 +++--- drivers/brcm/emmc/emmc_csl_sdcard.c | 6 ++- drivers/marvell/amb_adec.c | 13 +++--- drivers/marvell/ccu.c | 9 +++-- drivers/marvell/comphy/phy-comphy-cp110.c | 4 +- drivers/marvell/gwin.c | 9 +++-- drivers/marvell/io_win.c | 9 +++-- drivers/marvell/iob.c | 9 +++-- drivers/marvell/mc_trustzone/mc_trustzone.c | 7 +++- drivers/mtd/spi-mem/spi_mem.c | 4 +- drivers/nxp/ddr/nxp-ddr/ddr.c | 9 +++-- include/lib/libc/aarch32/inttypes_.h | 21 ++++++++++ include/lib/libc/aarch32/stdint_.h | 28 +++++++++++++ include/lib/libc/aarch64/inttypes_.h | 21 ++++++++++ include/lib/libc/aarch64/stdint_.h | 31 +++++++++++++++ include/lib/libc/inttypes.h | 47 ++++++++++++++++++++++ include/lib/libc/stdint.h | 18 +-------- lib/bl_aux_params/bl_aux_params.c | 4 +- lib/extensions/amu/aarch64/amu.c | 4 +- plat/arm/board/fvp/fconf/fconf_hw_config_getter.c | 5 ++- plat/common/aarch64/plat_common.c | 6 ++- plat/common/plat_spmd_manifest.c | 8 ++-- plat/hisilicon/hikey/hikey_bl1_setup.c | 4 +- plat/hisilicon/poplar/bl31_plat_setup.c | 4 +- plat/imx/imx8qm/imx8qm_bl31_setup.c | 24 ++++++------ plat/imx/imx8qx/imx8qx_bl31_setup.c | 24 ++++++------ plat/marvell/armada/a3k/common/a3700_ea.c | 6 ++- plat/nvidia/tegra/common/tegra_bl31_setup.c | 7 ++-- plat/nvidia/tegra/soc/t186/drivers/mce/mce.c | 4 +- plat/nvidia/tegra/soc/t194/drivers/mce/mce.c | 4 +- plat/nvidia/tegra/soc/t194/plat_ras.c | 7 ++-- plat/nvidia/tegra/soc/t210/plat_sip_calls.c | 5 ++- plat/nxp/common/setup/ls_bl31_setup.c | 6 ++- plat/renesas/rcar/bl2_plat_setup.c | 6 ++- plat/renesas/rzg/bl2_plat_setup.c | 4 +- plat/rpi/rpi4/rpi4_bl31_setup.c | 4 +- plat/xilinx/common/plat_startup.c | 10 +++-- services/spd/trusty/trusty.c | 10 +++-- services/std_svc/sdei/sdei_intr_mgmt.c | 12 +++--- services/std_svc/sdei/sdei_main.c | 48 ++++++++++++----------- services/std_svc/spmd/spmd_main.c | 18 +++++---- services/std_svc/spmd/spmd_pm.c | 7 +++- 43 files changed, 359 insertions(+), 145 deletions(-) create mode 100644 include/lib/libc/aarch32/inttypes_.h create mode 100644 include/lib/libc/aarch32/stdint_.h create mode 100644 include/lib/libc/aarch64/inttypes_.h create mode 100644 include/lib/libc/aarch64/stdint_.h create mode 100644 include/lib/libc/inttypes.h diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index 01c9ec58f..55e153212 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -271,7 +273,7 @@ tsp_args_t *tsp_cpu_resume_main(uint64_t max_off_pwrlvl, #if LOG_LEVEL >= LOG_LEVEL_INFO spin_lock(&console_lock); - INFO("TSP: cpu 0x%lx resumed. maximum off power level %lld\n", + INFO("TSP: cpu 0x%lx resumed. maximum off power level %" PRId64 "\n", read_mpidr(), max_off_pwrlvl); INFO("TSP: cpu 0x%lx: %d smcs, %d erets %d cpu resume requests\n", read_mpidr(), @@ -375,7 +377,7 @@ tsp_args_t *tsp_smc_handler(uint64_t func, #if LOG_LEVEL >= LOG_LEVEL_INFO spin_lock(&console_lock); - INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(), + INFO("TSP: cpu 0x%lx received %s smc 0x%" PRIx64 "\n", read_mpidr(), ((func >> 31) & 1) == 1 ? "fast" : "yielding", func); INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index 64e01ea6d..17ff397cd 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include @@ -402,7 +404,7 @@ static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size, addr_range = fdt_read_prop_cells(value + child_addr_size + parent_addr_size, range_size); - VERBOSE("DT: Address %llx mapped to %llx with range %llx\n", + VERBOSE("DT: Address %" PRIx64 " mapped to %" PRIx64 " with range %" PRIx64 "\n", local_address, parent_address, addr_range); /* Perform range check */ @@ -413,8 +415,8 @@ static bool fdtw_xlat_hit(const uint32_t *value, int child_addr_size, /* Found hit for the addr range that needs to be translated */ *translated_addr = parent_address + (base_address - local_address); - VERBOSE("DT: child address %llx mapped to %llx in parent bus\n", - local_address, parent_address); + VERBOSE("DT: child address %" PRIx64 "mapped to %" PRIx64 " in parent bus\n", + local_address, parent_address); return true; } @@ -470,8 +472,8 @@ static uint64_t fdtw_search_all_xlat_entries(const void *dtb, next_entry = next_entry + ncells_xlat; } - INFO("DT: No translation found for address %llx in node %s\n", - base_address, fdt_get_name(dtb, local_bus, NULL)); + INFO("DT: No translation found for address %" PRIx64 " in node %s\n", + base_address, fdt_get_name(dtb, local_bus, NULL)); return ILLEGAL_ADDR; } diff --git a/drivers/brcm/emmc/emmc_csl_sdcard.c b/drivers/brcm/emmc/emmc_csl_sdcard.c index d6ad4bc9c..9e2c618d9 100644 --- a/drivers/brcm/emmc/emmc_csl_sdcard.c +++ b/drivers/brcm/emmc/emmc_csl_sdcard.c @@ -4,9 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include +#include #include #include -#include #include #include @@ -521,7 +523,7 @@ static int xfer_data(struct sd_handle *handle, { int rc = SD_OK; - VERBOSE("XFER: dest: 0x%llx, addr: 0x%x, size: 0x%x bytes\n", + VERBOSE("XFER: dest: 0x%" PRIx64 ", addr: 0x%x, size: 0x%x bytes\n", (uint64_t)base, addr, length); if ((length / handle->device->cfg.blockSize) > 1) { diff --git a/drivers/marvell/amb_adec.c b/drivers/marvell/amb_adec.c index 1f671058d..d78fa2517 100644 --- a/drivers/marvell/amb_adec.c +++ b/drivers/marvell/amb_adec.c @@ -7,6 +7,9 @@ /* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */ +#include +#include + #include #include @@ -44,10 +47,10 @@ static void amb_check_win(struct addr_map_win *win, uint32_t win_num) /* make sure the base address is in 16-bit range */ if (win->base_addr > AMB_BASE_ADDR_MASK) { - WARN("Window %d: base address is too big 0x%llx\n", + WARN("Window %d: base address is too big 0x%" PRIx64 "\n", win_num, win->base_addr); win->base_addr = AMB_BASE_ADDR_MASK; - WARN("Set the base address to 0x%llx\n", win->base_addr); + WARN("Set the base address to 0x%" PRIx64 "\n", win->base_addr); } base_addr = win->base_addr << AMB_BASE_OFFSET; @@ -57,15 +60,15 @@ static void amb_check_win(struct addr_map_win *win, uint32_t win_num) win->base_addr = ALIGN_UP(base_addr, AMB_WIN_ALIGNMENT_1M); WARN("Window %d: base address unaligned to 0x%x\n", win_num, AMB_WIN_ALIGNMENT_1M); - WARN("Align up the base address to 0x%llx\n", win->base_addr); + WARN("Align up the base address to 0x%" PRIx64 "\n", win->base_addr); } /* size parameter validity check */ if (!IS_POWER_OF_2(win->win_size)) { - WARN("Window %d: window size is not power of 2 (0x%llx)\n", + WARN("Window %d: window size is not power of 2 (0x%" PRIx64 ")\n", win_num, win->win_size); win->win_size = ROUND_UP_TO_POW_OF_2(win->win_size); - WARN("Rounding size to 0x%llx\n", win->win_size); + WARN("Rounding size to 0x%" PRIx64 "\n", win->win_size); } } diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c index b4251f49b..c206f1168 100644 --- a/drivers/marvell/ccu.c +++ b/drivers/marvell/ccu.c @@ -7,6 +7,9 @@ /* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */ +#include +#include + #include #include #include @@ -84,7 +87,7 @@ static void dump_ccu(int ap_index) win_id)); start = ((uint64_t)alr << ADDRESS_SHIFT); end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT); - printf("\tccu%d %02x 0x%016llx 0x%016llx\n", + printf("\tccu%d %02x 0x%016" PRIx64 " 0x%016" PRIx64 "\n", win_id, target_id, start, end); } } @@ -99,14 +102,14 @@ void ccu_win_check(struct addr_map_win *win) /* check if address is aligned to 1M */ if (IS_NOT_ALIGN(win->base_addr, CCU_WIN_ALIGNMENT)) { win->base_addr = ALIGN_UP(win->base_addr, CCU_WIN_ALIGNMENT); - NOTICE("%s: Align up the base address to 0x%llx\n", + NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n", __func__, win->base_addr); } /* size parameter validity check */ if (IS_NOT_ALIGN(win->win_size, CCU_WIN_ALIGNMENT)) { win->win_size = ALIGN_UP(win->win_size, CCU_WIN_ALIGNMENT); - NOTICE("%s: Aligning size to 0x%llx\n", + NOTICE("%s: Aligning size to 0x%" PRIx64 "\n", __func__, win->win_size); } } diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c index e7cde759f..fa9fe4100 100644 --- a/drivers/marvell/comphy/phy-comphy-cp110.c +++ b/drivers/marvell/comphy/phy-comphy-cp110.c @@ -8,6 +8,8 @@ /* Marvell CP110 SoC COMPHY unit driver */ #include +#include +#include #include #include @@ -102,7 +104,7 @@ static void mvebu_cp110_get_ap_and_cp_nr(uint8_t *ap_nr, uint8_t *cp_nr, *cp_nr = (((comphy_base & ~0xffffff) - MVEBU_AP_IO_BASE(*ap_nr)) / MVEBU_CP_OFFSET); - debug("cp_base 0x%llx, ap_io_base 0x%lx, cp_offset 0x%lx\n", + debug("cp_base 0x%" PRIx64 ", ap_io_base 0x%lx, cp_offset 0x%lx\n", comphy_base, (unsigned long)MVEBU_AP_IO_BASE(*ap_nr), (unsigned long)MVEBU_CP_OFFSET); } diff --git a/drivers/marvell/gwin.c b/drivers/marvell/gwin.c index 9d9430836..fa59cb033 100644 --- a/drivers/marvell/gwin.c +++ b/drivers/marvell/gwin.c @@ -7,6 +7,9 @@ /* GWIN unit device driver for Marvell AP810 SoC */ +#include +#include + #include #include #include @@ -49,14 +52,14 @@ static void gwin_check(struct addr_map_win *win) /* The base is always 64M aligned */ if (IS_NOT_ALIGN(win->base_addr, GWIN_ALIGNMENT_64M)) { win->base_addr &= ~(GWIN_ALIGNMENT_64M - 1); - NOTICE("%s: Align the base address to 0x%llx\n", + NOTICE("%s: Align the base address to 0x%" PRIx64 "\n", __func__, win->base_addr); } /* size parameter validity check */ if (IS_NOT_ALIGN(win->win_size, GWIN_ALIGNMENT_64M)) { win->win_size = ALIGN_UP(win->win_size, GWIN_ALIGNMENT_64M); - NOTICE("%s: Aligning window size to 0x%llx\n", + NOTICE("%s: Aligning window size to 0x%" PRIx64 "\n", __func__, win->win_size); } } @@ -167,7 +170,7 @@ static void dump_gwin(int ap_index) alr = (alr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT; ahr = mmio_read_32(GWIN_AHR_OFFSET(ap_index, win_num)); ahr = (ahr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT; - printf("\tgwin %d 0x%016llx 0x%016llx\n", + printf("\tgwin %d 0x%016" PRIx64 " 0x%016" PRIx64 "\n", (cr >> 8) & 0xF, alr, ahr); } } diff --git a/drivers/marvell/io_win.c b/drivers/marvell/io_win.c index c4257fa7c..124382ad9 100644 --- a/drivers/marvell/io_win.c +++ b/drivers/marvell/io_win.c @@ -7,6 +7,9 @@ /* IO Window unit device driver for Marvell AP807, AP807 and AP810 SoCs */ +#include +#include + #include #include #include @@ -44,14 +47,14 @@ static void io_win_check(struct addr_map_win *win) /* check if address is aligned to 1M */ if (IS_NOT_ALIGN(win->base_addr, IO_WIN_ALIGNMENT_1M)) { win->base_addr = ALIGN_UP(win->base_addr, IO_WIN_ALIGNMENT_1M); - NOTICE("%s: Align up the base address to 0x%llx\n", + NOTICE("%s: Align up the base address to 0x%" PRIx64 "\n", __func__, win->base_addr); } /* size parameter validity check */ if (IS_NOT_ALIGN(win->win_size, IO_WIN_ALIGNMENT_1M)) { win->win_size = ALIGN_UP(win->win_size, IO_WIN_ALIGNMENT_1M); - NOTICE("%s: Aligning size to 0x%llx\n", + NOTICE("%s: Aligning size to 0x%" PRIx64 "\n", __func__, win->win_size); } } @@ -170,7 +173,7 @@ static void dump_io_win(int ap_index) win_id)); start = ((uint64_t)alr << ADDRESS_SHIFT); end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT); - printf("\tio-win %d 0x%016llx 0x%016llx\n", + printf("\tio-win %d 0x%016" PRIx64 " 0x%016" PRIx64 "\n", trgt_id, start, end); } } diff --git a/drivers/marvell/iob.c b/drivers/marvell/iob.c index 29088aa92..1f3939560 100644 --- a/drivers/marvell/iob.c +++ b/drivers/marvell/iob.c @@ -7,6 +7,9 @@ /* IOW unit device driver for Marvell CP110 and CP115 SoCs */ +#include +#include + #include #include #include @@ -57,7 +60,7 @@ static void iob_win_check(struct addr_map_win *win, uint32_t win_num) win->base_addr = ALIGN_UP(win->base_addr, IOB_WIN_ALIGNMENT); ERROR("Window %d: base address unaligned to 0x%x\n", win_num, IOB_WIN_ALIGNMENT); - printf("Align up the base address to 0x%llx\n", + printf("Align up the base address to 0x%" PRIx64 "\n", win->base_addr); } @@ -66,7 +69,7 @@ static void iob_win_check(struct addr_map_win *win, uint32_t win_num) win->win_size = ALIGN_UP(win->win_size, IOB_WIN_ALIGNMENT); ERROR("Window %d: window size unaligned to 0x%x\n", win_num, IOB_WIN_ALIGNMENT); - printf("Aligning size to 0x%llx\n", win->win_size); + printf("Aligning size to 0x%" PRIx64 "\n", win->win_size); } } @@ -130,7 +133,7 @@ static void dump_iob(void) */ end = start + (16 << 20); } - printf("iob %02d %s 0x%016llx 0x%016llx\n", + printf("iob %02d %s 0x%016" PRIx64 " 0x%016" PRIx64 "\n", win_id, iob_target_name[target_id], start, end); } diff --git a/drivers/marvell/mc_trustzone/mc_trustzone.c b/drivers/marvell/mc_trustzone/mc_trustzone.c index 52b300676..648bd0e98 100644 --- a/drivers/marvell/mc_trustzone/mc_trustzone.c +++ b/drivers/marvell/mc_trustzone/mc_trustzone.c @@ -5,6 +5,9 @@ * https://spdx.org/licenses */ +#include +#include + #include #include #include @@ -39,7 +42,7 @@ void tz_enable_win(int ap_index, const struct addr_map_win *win, int win_id) /* map the window size to trustzone register convention */ tz_size = fls(TZ_SIZE(win->win_size)); - VERBOSE("%s: window size = 0x%llx maps to tz_size %d\n", + VERBOSE("%s: window size = 0x%" PRIx64 " maps to tz_size %d\n", __func__, win->win_size, tz_size); if (tz_size < 0 || tz_size > 31) { ERROR("Using not allowed size for MC TrustZone window %d!\n", @@ -49,7 +52,7 @@ void tz_enable_win(int ap_index, const struct addr_map_win *win, int win_id) if (base & 0xfff) { base = base & ~0xfff; - WARN("Attempt to open MC TZ win. at 0x%llx, truncate to 0x%x\n", + WARN("Attempt to open MC TZ win. at 0x%" PRIx64 ", truncate to 0x%x\n", win->base_addr, base); } diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c index 63ea7699b..010e8b62a 100644 --- a/drivers/mtd/spi-mem/spi_mem.c +++ b/drivers/mtd/spi-mem/spi_mem.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include @@ -150,7 +152,7 @@ int spi_mem_exec_op(const struct spi_mem_op *op) const struct spi_bus_ops *ops = spi_slave.ops; int ret; - VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n", + VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%" PRIx64 " len:%x\n", __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth, op->data.buswidth, op->addr.val, op->data.nbytes); diff --git a/drivers/nxp/ddr/nxp-ddr/ddr.c b/drivers/nxp/ddr/nxp-ddr/ddr.c index 216e05c7c..c051b3b25 100644 --- a/drivers/nxp/ddr/nxp-ddr/ddr.c +++ b/drivers/nxp/ddr/nxp-ddr/ddr.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -850,7 +851,7 @@ long long dram_init(struct ddr_info *priv priv->ip_rev = ip_rev; #ifndef CONFIG_STATIC_DDR - INFO("time base %llu ms\n", time_base); + INFO("time base %" PRIu64 " ms\n", time_base); debug("Parse DIMM SPD(s)\n"); valid_spd_mask = parse_spd(priv); @@ -870,7 +871,7 @@ long long dram_init(struct ddr_info *priv #endif time = get_timer_val(time_base); - INFO("Time after parsing SPD %llu ms\n", time); + INFO("Time after parsing SPD %" PRIu64 " ms\n", time); debug("Synthesize configurations\n"); ret = synthesize_ctlr(priv); if (ret != 0) { @@ -911,7 +912,7 @@ long long dram_init(struct ddr_info *priv } time = get_timer_val(time_base); - INFO("Time before programming controller %llu ms\n", time); + INFO("Time before programming controller %" PRIu64 " ms\n", time); debug("Program controller registers\n"); ret = write_ddrc_regs(priv); if (ret != 0) { @@ -924,7 +925,7 @@ long long dram_init(struct ddr_info *priv print_ddr_info(priv->ddr[0]); time = get_timer_val(time_base); - INFO("Time used by DDR driver %llu ms\n", time); + INFO("Time used by DDR driver %" PRIu64 " ms\n", time); return dram_size; } diff --git a/include/lib/libc/aarch32/inttypes_.h b/include/lib/libc/aarch32/inttypes_.h new file mode 100644 index 000000000..11d2d3525 --- /dev/null +++ b/include/lib/libc/aarch32/inttypes_.h @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * Portions copyright (c) 2020, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef INTTYPES__H +#define INTTYPES__H + +#define PRId64 "lld" /* int64_t */ +#define PRIi64 "lli" /* int64_t */ +#define PRIo64 "llo" /* int64_t */ +#define PRIu64 "llu" /* uint64_t */ +#define PRIx64 "llx" /* uint64_t */ +#define PRIX64 "llX" /* uint64_t */ + +#endif /* INTTYPES__H */ diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h new file mode 100644 index 000000000..dafe142b5 --- /dev/null +++ b/include/lib/libc/aarch32/stdint_.h @@ -0,0 +1,28 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * Portions copyright (c) 2020, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef STDINT__H +#define STDINT__H + +#define INT64_MAX LLONG_MAX +#define INT64_MIN LLONG_MIN +#define UINT64_MAX ULLONG_MAX + +#define INT64_C(x) x ## LL +#define UINT64_C(x) x ## ULL + +typedef long long int64_t; +typedef unsigned long long uint64_t; +typedef long long int64_least_t; +typedef unsigned long long uint64_least_t; +typedef long long int64_fast_t; +typedef unsigned long long uint64_fast_t; + +#endif diff --git a/include/lib/libc/aarch64/inttypes_.h b/include/lib/libc/aarch64/inttypes_.h new file mode 100644 index 000000000..197d627bc --- /dev/null +++ b/include/lib/libc/aarch64/inttypes_.h @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * Portions copyright (c) 2020, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef INTTYPES__H +#define INTTYPES__H + +#define PRId64 "ld" /* int64_t */ +#define PRIi64 "li" /* int64_t */ +#define PRIo64 "lo" /* int64_t */ +#define PRIu64 "lu" /* uint64_t */ +#define PRIx64 "lx" /* uint64_t */ +#define PRIX64 "lX" /* uint64_t */ + +#endif /* INTTYPES__H */ diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h new file mode 100644 index 000000000..56e9f1b4c --- /dev/null +++ b/include/lib/libc/aarch64/stdint_.h @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * Portions copyright (c) 2020, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef STDINT__H +#define STDINT__H + +#define INT64_MAX LONG_MAX +#define INT64_MIN LONG_MIN +#define UINT64_MAX ULONG_MAX + +#define INT64_C(x) x ## L +#define UINT64_C(x) x ## UL + +typedef long int64_t; +typedef unsigned long uint64_t; +typedef long int64_least_t; +typedef unsigned long uint64_least_t; +typedef long int64_fast_t; +typedef unsigned long uint64_fast_t; + +typedef __int128 int128_t; +typedef unsigned __int128 uint128_t; + +#endif diff --git a/include/lib/libc/inttypes.h b/include/lib/libc/inttypes.h new file mode 100644 index 000000000..0f9e8c612 --- /dev/null +++ b/include/lib/libc/inttypes.h @@ -0,0 +1,47 @@ +/* + * Copyright 2020 Broadcom + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * Portions copyright (c) 2020, ARM Limited and Contributors. + * All rights reserved. + */ + +#ifndef INTTYPES_H +#define INTTYPES_H + +#include +#include + +#define PRId8 "d" /* int8_t */ +#define PRId16 "d" /* int16_t */ +#define PRId32 "d" /* int32_t */ +#define PRIdPTR "d" /* intptr_t */ + +#define PRIi8 "i" /* int8_t */ +#define PRIi16 "i" /* int16_t */ +#define PRIi32 "i" /* int32_t */ +#define PRIiPTR "i" /* intptr_t */ + +#define PRIo8 "o" /* int8_t */ +#define PRIo16 "o" /* int16_t */ +#define PRIo32 "o" /* int32_t */ +#define PRIoPTR "o" /* intptr_t */ + +#define PRIu8 "u" /* uint8_t */ +#define PRIu16 "u" /* uint16_t */ +#define PRIu32 "u" /* uint32_t */ +#define PRIuPTR "u" /* uintptr_t */ + +#define PRIx8 "x" /* uint8_t */ +#define PRIx16 "x" /* uint16_t */ +#define PRIx32 "x" /* uint32_t */ +#define PRIxPTR "x" /* uintptr_t */ + +#define PRIX8 "X" /* uint8_t */ +#define PRIX16 "X" /* uint16_t */ +#define PRIX32 "X" /* uint32_t */ +#define PRIXPTR "X" /* uintptr_t */ + +#endif diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h index 818870e16..e96a25cd3 100644 --- a/include/lib/libc/stdint.h +++ b/include/lib/libc/stdint.h @@ -12,6 +12,7 @@ #define STDINT_H #include +#include #define INT8_MAX CHAR_MAX #define INT8_MIN CHAR_MIN @@ -25,10 +26,6 @@ #define INT32_MIN INT_MIN #define UINT32_MAX UINT_MAX -#define INT64_MAX LLONG_MAX -#define INT64_MIN LLONG_MIN -#define UINT64_MAX ULLONG_MAX - #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define UINT_LEAST8_MAX UINT8_MAX @@ -77,12 +74,10 @@ #define INT8_C(x) x #define INT16_C(x) x #define INT32_C(x) x -#define INT64_C(x) x ## LL #define UINT8_C(x) x #define UINT16_C(x) x #define UINT32_C(x) x ## U -#define UINT64_C(x) x ## ULL #define INTMAX_C(x) x ## LL #define UINTMAX_C(x) x ## ULL @@ -90,32 +85,26 @@ typedef signed char int8_t; typedef short int16_t; typedef int int32_t; -typedef long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; typedef signed char int8_least_t; typedef short int16_least_t; typedef int int32_least_t; -typedef long long int64_least_t; typedef unsigned char uint8_least_t; typedef unsigned short uint16_least_t; typedef unsigned int uint32_least_t; -typedef unsigned long long uint64_least_t; typedef int int8_fast_t; typedef int int16_fast_t; typedef int int32_fast_t; -typedef long long int64_fast_t; typedef unsigned int uint8_fast_t; typedef unsigned int uint16_fast_t; typedef unsigned int uint32_fast_t; -typedef unsigned long long uint64_fast_t; typedef long intptr_t; typedef unsigned long uintptr_t; @@ -130,9 +119,4 @@ typedef unsigned long long uintmax_t; typedef long register_t; typedef unsigned long u_register_t; -#ifdef __aarch64__ -typedef __int128 int128_t; -typedef unsigned __int128 uint128_t; -#endif /* __aarch64__ */ - #endif /* STDINT_H */ diff --git a/lib/bl_aux_params/bl_aux_params.c b/lib/bl_aux_params/bl_aux_params.c index 7a8115c61..7f357b7c2 100644 --- a/lib/bl_aux_params/bl_aux_params.c +++ b/lib/bl_aux_params/bl_aux_params.c @@ -3,6 +3,8 @@ * * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include #include #include @@ -25,7 +27,7 @@ void bl_aux_params_parse(u_register_t head, break; #endif default: - ERROR("Ignoring unknown BL aux parameter: 0x%llx", + ERROR("Ignoring unknown BL aux parameter: 0x%" PRIx64, p->type); break; } diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c index 35efd21e0..d329c3d33 100644 --- a/lib/extensions/amu/aarch64/amu.c +++ b/lib/extensions/amu/aarch64/amu.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include "../amu_private.h" #include @@ -343,7 +345,7 @@ static bool amu_group0_voffset_supported(uint64_t idx) default: ERROR("AMU: can't set up virtual offset for unknown " - "architected counter %llu!\n", idx); + "architected counter %" PRIu64 "!\n", idx); panic(); } diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c index 35a777b6f..45e3b7eb2 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -5,6 +5,9 @@ */ #include +#include +#include + #include #include #include @@ -229,7 +232,7 @@ int fconf_populate_uart_config(uintptr_t config) uart_serial_config.uart_base = translated_addr; - VERBOSE("FCONF: UART serial device base address: %llx\n", + VERBOSE("FCONF: UART serial device base address: %" PRIx64 "\n", uart_serial_config.uart_base); /* diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index 345fec36a..38a57861f 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -53,7 +55,7 @@ unsigned int platform_core_pos_helper(unsigned long mpidr) */ void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) { - WARN("Spurious SDEI interrupt %u on masked PE %llx\n", intr, mpidr); + WARN("Spurious SDEI interrupt %u on masked PE %" PRIx64 "\n", intr, mpidr); } /* @@ -93,7 +95,7 @@ void plat_default_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *co ERROR_NL(); ERROR("Unhandled External Abort received on 0x%lx from %s\n", read_mpidr_el1(), get_el_str(level)); - ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); + ERROR("exception reason=%u syndrome=0x%" PRIx64 "\n", ea_reason, syndrome); #if HANDLE_EA_EL3_FIRST /* Skip backtrace for lower EL */ if (level != MODE_EL3) { diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 8f4018c7c..b1fc13cee 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -6,8 +6,10 @@ #include #include -#include +#include #include +#include +#include #include #include @@ -80,8 +82,8 @@ static int manifest_parse_attribute(spmc_manifest_attribute_t *attr, VERBOSE(" version: %u.%u\n", attr->major_version, attr->minor_version); VERBOSE(" spmc_id: 0x%x\n", attr->spmc_id); VERBOSE(" binary_size: 0x%x\n", attr->binary_size); - VERBOSE(" load_address: 0x%llx\n", attr->load_address); - VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); + VERBOSE(" load_address: 0x%" PRIx64 "\n", attr->load_address); + VERBOSE(" entrypoint: 0x%" PRIx64 "\n", attr->entrypoint); return 0; } diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c index 01c48ec58..31ff8206e 100644 --- a/plat/hisilicon/hikey/hikey_bl1_setup.c +++ b/plat/hisilicon/hikey/hikey_bl1_setup.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include @@ -155,7 +157,7 @@ void bl1_plat_set_ep_info(unsigned int image_id, __asm__ volatile ("msr cpacr_el1, %0" : : "r"(data)); __asm__ volatile ("mrs %0, cpacr_el1" : "=r"(data)); } while ((data & (3 << 20)) != (3 << 20)); - INFO("cpacr_el1:0x%llx\n", data); + INFO("cpacr_el1:0x%" PRIx64 "\n", data); ep_info->args.arg0 = 0xffff & read_mpidr(); ep_info->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c index a4e17cabc..fe60ddcb1 100644 --- a/plat/hisilicon/poplar/bl31_plat_setup.c +++ b/plat/hisilicon/poplar/bl31_plat_setup.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include @@ -130,6 +132,6 @@ void bl31_plat_arch_setup(void) BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END); - INFO("Boot BL33 from 0x%lx for %llu Bytes\n", + INFO("Boot BL33 from 0x%lx for %" PRIu64 " Bytes\n", bl33_image_ep_info.pc, bl33_image_ep_info.args.arg2); } diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c index 4ca6a5db4..d9c91107c 100644 --- a/plat/imx/imx8qm/imx8qm_bl31_setup.c +++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -261,14 +263,14 @@ void mx8_partition_resources(void) err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end); if (err) ERROR("Memreg get info failed, %u\n", mr); - NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end); if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) { mr_record = mr; /* Record the mr for ATF running */ } else { err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \ - err %d\n", start, end, err); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \ + err %d\n", start, end, err); } } } @@ -280,23 +282,23 @@ void mx8_partition_resources(void) if ((BL31_LIMIT - 1) < end) { err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end); if (err) - ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", - (sc_faddr_t)BL31_LIMIT, end); + ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + (sc_faddr_t)BL31_LIMIT, end); err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", - (sc_faddr_t)BL31_LIMIT, end); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + (sc_faddr_t)BL31_LIMIT, end); } if (start < (BL31_BASE - 1)) { err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1); if (err) - ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", - start, (sc_faddr_t)BL31_BASE - 1); + ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + start, (sc_faddr_t)BL31_BASE - 1); err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", - start, (sc_faddr_t)BL31_BASE - 1); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + start, (sc_faddr_t)BL31_BASE - 1); } } diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c index 3ff540017..3739cd681 100644 --- a/plat/imx/imx8qx/imx8qx_bl31_setup.c +++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c @@ -5,7 +5,9 @@ */ #include +#include #include +#include #include @@ -238,14 +240,14 @@ void imx8_partition_resources(void) if (err) ERROR("Memreg get info failed, %u\n", mr); - NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + NOTICE("Memreg %u 0x%" PRIx64 " -- 0x%" PRIx64 "\n", mr, start, end); if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) { mr_record = mr; /* Record the mr for ATF running */ } else { err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \ - err %d\n", start, end, err); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 ", \ + err %d\n", start, end, err); } } } @@ -257,23 +259,23 @@ void imx8_partition_resources(void) if ((BL31_LIMIT - 1) < end) { err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end); if (err) - ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", - (sc_faddr_t)BL31_LIMIT, end); + ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + (sc_faddr_t)BL31_LIMIT, end); err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", - (sc_faddr_t)BL31_LIMIT, end); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + (sc_faddr_t)BL31_LIMIT, end); } if (start < (BL31_BASE - 1)) { err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1); if (err) - ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", - start, (sc_faddr_t)BL31_BASE - 1); + ERROR("sc_rm_memreg_alloc failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + start, (sc_faddr_t)BL31_BASE - 1); err = sc_rm_assign_memreg(ipc_handle, os_part, mr); if (err) - ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", - start, (sc_faddr_t)BL31_BASE - 1); + ERROR("Memreg assign failed, 0x%" PRIx64 " -- 0x%" PRIx64 "\n", + start, (sc_faddr_t)BL31_BASE - 1); } } diff --git a/plat/marvell/armada/a3k/common/a3700_ea.c b/plat/marvell/armada/a3k/common/a3700_ea.c index 4a58fc6a4..bc12845a5 100644 --- a/plat/marvell/armada/a3k/common/a3700_ea.c +++ b/plat/marvell/armada/a3k/common/a3700_ea.c @@ -4,6 +4,10 @@ * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses */ + +#include +#include + #include #include #include @@ -72,7 +76,7 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, syndrome == A53_SERR_INT_AXI_SLVERR_ON_EXTERNAL_ACCESS) { ERROR_NL(); ERROR("Ignoring Asynchronous External Abort with" - " syndrome 0x%llx received on 0x%lx from %s\n", + " syndrome 0x%" PRIx64 " received on 0x%lx from %s\n", syndrome, read_mpidr_el1(), get_el_str(level)); ERROR("SError interrupt: AXI SLVERR on external access\n"); ERROR("This indicates a bug in pci-aardvark.c driver\n"); diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index cb4886f1a..6a3eae0dd 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -336,7 +337,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) * Sanity check the input values */ if ((base == 0U) || (size_in_bytes == 0U)) { - ERROR("NS address 0x%llx (%lld bytes) is invalid\n", + ERROR("NS address 0x%" PRIx64 " (%" PRId64 " bytes) is invalid\n", base, size_in_bytes); return -EINVAL; } @@ -347,7 +348,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) if ((base < TEGRA_DRAM_BASE) || (base >= TEGRA_DRAM_END) || (end > TEGRA_DRAM_END)) { - ERROR("NS address 0x%llx is out-of-bounds!\n", base); + ERROR("NS address 0x%" PRIx64 " is out-of-bounds!\n", base); return -EFAULT; } @@ -356,7 +357,7 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes) * to check if the NS DRAM range overlaps the TZDRAM aperture. */ if ((base < (uint64_t)TZDRAM_END) && (end > tegra_bl31_phys_base)) { - ERROR("NS address 0x%llx overlaps TZDRAM!\n", base); + ERROR("NS address 0x%" PRIx64 " overlaps TZDRAM!\n", base); return -ENOTSUP; } diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index 54d3b2ccd..aebacebf2 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -341,7 +343,7 @@ int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1, break; default: - ERROR("unknown MCE command (%llu)\n", cmd); + ERROR("unknown MCE command (%" PRIu64 ")\n", cmd); ret = EINVAL; break; } diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c index e3d5bd513..af1c0aa26 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -16,8 +16,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -69,7 +71,7 @@ int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1, break; default: - ERROR("unknown MCE command (%llu)\n", cmd); + ERROR("unknown MCE command (%" PRIu64 ")\n", cmd); ret = -EINVAL; break; } diff --git a/plat/nvidia/tegra/soc/t194/plat_ras.c b/plat/nvidia/tegra/soc/t194/plat_ras.c index a32240339..dbd62727e 100644 --- a/plat/nvidia/tegra/soc/t194/plat_ras.c +++ b/plat/nvidia/tegra/soc/t194/plat_ras.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include #include @@ -54,7 +55,7 @@ static void tegra194_ea_handler(unsigned int ea_reason, uint64_t syndrome, ras_lock(); - ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%llx\n", + ERROR("MPIDR 0x%lx: exception reason=%u syndrome=0x%" PRIx64 "\n", read_mpidr(), ea_reason, syndrome); /* Call RAS EA handler */ @@ -146,7 +147,7 @@ void tegra194_ras_enable(void) /* enable the supported errors */ err_ctrl |= err_fr; - VERBOSE("errselr_el1:0x%x, erxfr:0x%llx, err_ctrl:0x%llx\n", + VERBOSE("errselr_el1:0x%x, erxfr:0x%" PRIx64 ", err_ctrl:0x%" PRIx64 "\n", idx_start + j, err_fr, err_ctrl); /* enable specified errors, or set to 0 if no supported error */ @@ -288,7 +289,7 @@ static int32_t tegra194_ras_node_handler(uint32_t errselr, const char *name, /* keep the log print same as linux arm64_ras driver. */ ERROR("**************************************\n"); ERROR("RAS Error in %s, ERRSELR_EL1=0x%x:\n", name, errselr); - ERROR("\tStatus = 0x%llx\n", status); + ERROR("\tStatus = 0x%" PRIx64 "\n", status); /* Print uncorrectable errror information. */ if (ERR_STATUS_GET_FIELD(status, UE) != 0U) { diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c index 904f8d62e..e3484bea9 100644 --- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c @@ -5,6 +5,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include + #include #include #include @@ -71,7 +74,7 @@ int plat_sip_handler(uint32_t smc_fid, case PMC_CRYPTO_OP_0: case PMC_TSC_MULT_0: case PMC_STICKY_BIT: - ERROR("%s: error offset=0x%llx\n", __func__, x2); + ERROR("%s: error offset=0x%" PRIx64 "\n", __func__, x2); return -EFAULT; default: /* Valid register */ diff --git a/plat/nxp/common/setup/ls_bl31_setup.c b/plat/nxp/common/setup/ls_bl31_setup.c index 6cf6ae36a..bd0ab4fb7 100644 --- a/plat/nxp/common/setup/ls_bl31_setup.c +++ b/plat/nxp/common/setup/ls_bl31_setup.c @@ -6,6 +6,8 @@ */ #include +#include +#include #ifdef LS_EL3_INTERRUPT_HANDLER #include @@ -126,7 +128,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, loc_dram_regions_info->num_dram_regions; dram_regions_info.total_dram_size = loc_dram_regions_info->total_dram_size; - VERBOSE("Number of DRAM Regions = %llx\n", + VERBOSE("Number of DRAM Regions = %" PRIx64 "\n", dram_regions_info.num_dram_regions); for (i = 0; i < dram_regions_info.num_dram_regions; @@ -135,7 +137,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, loc_dram_regions_info->region[i].addr; dram_regions_info.region[i].size = loc_dram_regions_info->region[i].size; - VERBOSE("DRAM%d Size = %llx\n", i, + VERBOSE("DRAM%d Size = %" PRIx64 "\n", i, dram_regions_info.region[i].size); } rcw_porsr1 = bl31_image_ep_info.args.arg4; diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index e07b96f56..bbfa16927 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include #include #include @@ -622,7 +624,7 @@ static void bl2_add_dram_entry(uint64_t start, uint64_t size) return; err: - NOTICE("BL2: Cannot add memory node [%llx - %llx] to FDT (ret=%i)\n", + NOTICE("BL2: Cannot add memory node [%" PRIx64 " - %" PRIx64 "] to FDT (ret=%i)\n", start, start + size - 1, ret); panic(); } @@ -638,7 +640,7 @@ static void bl2_advertise_dram_entries(uint64_t dram_config[8]) if (!size) continue; - NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n", + NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n", chan, start, start + size - 1, (size >> 30) ? : size >> 20, (size >> 30) ? "G" : "M"); diff --git a/plat/renesas/rzg/bl2_plat_setup.c b/plat/renesas/rzg/bl2_plat_setup.c index ccc2562ee..e9dbd2058 100644 --- a/plat/renesas/rzg/bl2_plat_setup.c +++ b/plat/renesas/rzg/bl2_plat_setup.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include #include #include @@ -531,7 +533,7 @@ static void bl2_advertise_dram_entries(uint64_t dram_config[8]) continue; } - NOTICE("BL2: CH%d: %llx - %llx, %lld %siB\n", + NOTICE("BL2: CH%d: %" PRIx64 " - %" PRIx64 ", %" PRId64 " %siB\n", chan, start, start + size - 1U, (size >> 30) ? : size >> 20, (size >> 30) ? "G" : "M"); diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c index 525985913..2fb4d3df1 100644 --- a/plat/rpi/rpi4/rpi4_bl31_setup.c +++ b/plat/rpi/rpi4/rpi4_bl31_setup.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include @@ -234,7 +236,7 @@ static void remove_spintable_memreserve(void *dtb) fdt_del_mem_rsv(dtb, i); return; } - WARN("Keeping unknown /memreserve/ region at 0, size: %lld\n", + WARN("Keeping unknown /memreserve/ region at 0, size: %" PRId64 "\n", size); } } diff --git a/plat/xilinx/common/plat_startup.c b/plat/xilinx/common/plat_startup.c index 8c9a049dd..f02f41e91 100644 --- a/plat/xilinx/common/plat_startup.c +++ b/plat/xilinx/common/plat_startup.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -170,12 +172,12 @@ enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32, (ATFHandoffParams->magic[1] != 'L') || (ATFHandoffParams->magic[2] != 'N') || (ATFHandoffParams->magic[3] != 'X')) { - ERROR("BL31: invalid ATF handoff structure at %llx\n", + ERROR("BL31: invalid ATF handoff structure at %" PRIx64 "\n", atf_handoff_addr); return FSBL_HANDOFF_INVAL_STRUCT; } - VERBOSE("BL31: ATF handoff params at:0x%llx, entries:%u\n", + VERBOSE("BL31: ATF handoff params at:0x%" PRIx64 ", entries:%u\n", atf_handoff_addr, ATFHandoffParams->num_entries); if (ATFHandoffParams->num_entries > FSBL_MAX_PARTITIONS) { ERROR("BL31: ATF handoff params: too many partitions (%u/%u)\n", @@ -193,7 +195,7 @@ enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32, int target_estate, target_secure; int target_cpu, target_endianness, target_el; - VERBOSE("BL31: %zd: entry:0x%llx, flags:0x%llx\n", i, + VERBOSE("BL31: %zd: entry:0x%" PRIx64 ", flags:0x%" PRIx64 "\n", i, ATFHandoffParams->partition[i].entry_point, ATFHandoffParams->partition[i].flags); @@ -254,7 +256,7 @@ enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32, } } - VERBOSE("Setting up %s entry point to:%llx, el:%x\n", + VERBOSE("Setting up %s entry point to:%" PRIx64 ", el:%x\n", target_secure == FSBL_FLAGS_SECURE ? "BL32" : "BL33", ATFHandoffParams->partition[i].entry_point, target_el); diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index e102b8228..7daebcdd1 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -6,8 +6,10 @@ */ #include +#include #include #include +#include #include #include @@ -172,7 +174,7 @@ static uint64_t trusty_set_fiq_handler(void *handle, uint64_t cpu, struct trusty_cpu_ctx *ctx; if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) { - ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT); + ERROR("%s: cpu %" PRId64 " >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT); return (uint64_t)SM_ERR_INVALID_PARAMETERS; } @@ -204,7 +206,7 @@ static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0); if (ret.r0 != 1U) { - INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n", + INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %" PRId64 "\n", __func__, handle, ret.r0); } @@ -356,7 +358,7 @@ static void trusty_cpu_suspend(uint32_t off) ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0); if (ret.r0 != 0U) { - INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n", + INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %" PRId64 "\n", __func__, plat_my_core_pos(), ret.r0); } } @@ -367,7 +369,7 @@ static void trusty_cpu_resume(uint32_t on) ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0); if (ret.r0 != 0U) { - INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n", + INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %" PRId64 "\n", __func__, plat_my_core_pos(), ret.r0); } } diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c index 399c2ec91..87a1fb7dc 100644 --- a/services/std_svc/sdei/sdei_intr_mgmt.c +++ b/services/std_svc/sdei/sdei_intr_mgmt.c @@ -5,6 +5,8 @@ */ #include +#include +#include #include #include @@ -459,8 +461,8 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle, * Interrupts received while this PE was masked can't be * dispatched. */ - SDEI_LOG("interrupt %u on %llx while PE masked\n", map->intr, - mpidr); + SDEI_LOG("interrupt %u on %" PRIx64 " while PE masked\n", + map->intr, mpidr); if (is_event_shared(map)) sdei_map_lock(map); @@ -531,8 +533,8 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle, if (is_event_shared(map)) sdei_map_unlock(map); - SDEI_LOG("ACK %llx, ev:0x%x ss:%d spsr:%lx ELR:%lx\n", mpidr, map->ev_num, - sec_state, read_spsr_el3(), read_elr_el3()); + SDEI_LOG("ACK %" PRIx64 ", ev:0x%x ss:%d spsr:%lx ELR:%lx\n", + mpidr, map->ev_num, sec_state, read_spsr_el3(), read_elr_el3()); ctx = handle; @@ -703,7 +705,7 @@ int sdei_event_complete(bool resume, uint64_t pc) /* Having done sanity checks, pop dispatch */ (void) pop_dispatch(); - SDEI_LOG("EOI:%lx, 0x%x spsr:%lx elr:%lx\n", read_mpidr_el1(), + SDEI_LOG("EOI:%lx, %d spsr:%lx elr:%lx\n", read_mpidr_el1(), map->ev_num, read_spsr_el3(), read_elr_el3()); /* diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c index 4ceaae891..1f5510206 100644 --- a/services/std_svc/sdei/sdei_main.c +++ b/services/std_svc/sdei/sdei_main.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include @@ -961,33 +963,33 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, case SDEI_VERSION: SDEI_LOG("> VER\n"); ret = (int64_t) sdei_version(); - SDEI_LOG("< VER:%llx\n", ret); + SDEI_LOG("< VER:%" PRIx64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_REGISTER: x5 = SMC_GET_GP(ctx, CTX_GPREG_X5); - SDEI_LOG("> REG(n:0x%x e:%llx a:%llx f:%x m:%llx)\n", ev_num, + SDEI_LOG("> REG(n:%d e:%" PRIx64 " a:%" PRIx64 " f:%x m:%" PRIx64 "\n", ev_num, x2, x3, (int) x4, x5); ret = sdei_event_register(ev_num, x2, x3, x4, x5); - SDEI_LOG("< REG:%lld\n", ret); + SDEI_LOG("< REG:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_ENABLE: SDEI_LOG("> ENABLE(n:%d)\n", (int) x1); ret = sdei_event_enable(ev_num); - SDEI_LOG("< ENABLE:%lld\n", ret); + SDEI_LOG("< ENABLE:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_DISABLE: SDEI_LOG("> DISABLE(n:0x%x)\n", ev_num); ret = sdei_event_disable(ev_num); - SDEI_LOG("< DISABLE:%lld\n", ret); + SDEI_LOG("< DISABLE:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_CONTEXT: SDEI_LOG("> CTX(p:%d):%lx\n", (int) x1, read_mpidr_el1()); ret = sdei_event_context(ctx, (unsigned int) x1); - SDEI_LOG("< CTX:%lld\n", ret); + SDEI_LOG("< CTX:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_COMPLETE_AND_RESUME: @@ -995,10 +997,10 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, /* Fallthrough */ case SDEI_EVENT_COMPLETE: - SDEI_LOG("> COMPLETE(r:%u sta/ep:%llx):%lx\n", - (unsigned int) resume, x1, read_mpidr_el1()); + SDEI_LOG("> COMPLETE(r:%u sta/ep:%" PRIx64 "):%lx\n", + (unsigned int) resume, x1, read_mpidr_el1()); ret = sdei_event_complete(resume, x1); - SDEI_LOG("< COMPLETE:%llx\n", ret); + SDEI_LOG("< COMPLETE:%" PRIx64 "\n", ret); /* * Set error code only if the call failed. If the call @@ -1015,19 +1017,19 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, case SDEI_EVENT_STATUS: SDEI_LOG("> STAT(n:0x%x)\n", ev_num); ret = sdei_event_status(ev_num); - SDEI_LOG("< STAT:%lld\n", ret); + SDEI_LOG("< STAT:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_GET_INFO: SDEI_LOG("> INFO(n:0x%x, %d)\n", ev_num, (int) x2); ret = sdei_event_get_info(ev_num, (int) x2); - SDEI_LOG("< INFO:%lld\n", ret); + SDEI_LOG("< INFO:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_UNREGISTER: SDEI_LOG("> UNREG(n:0x%x)\n", ev_num); ret = sdei_event_unregister(ev_num); - SDEI_LOG("< UNREG:%lld\n", ret); + SDEI_LOG("< UNREG:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_PE_UNMASK: @@ -1039,49 +1041,49 @@ uint64_t sdei_smc_handler(uint32_t smc_fid, case SDEI_PE_MASK: SDEI_LOG("> MASK:%lx\n", read_mpidr_el1()); ret = sdei_pe_mask(); - SDEI_LOG("< MASK:%lld\n", ret); + SDEI_LOG("< MASK:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_INTERRUPT_BIND: SDEI_LOG("> BIND(%d)\n", (int) x1); ret = sdei_interrupt_bind((unsigned int) x1); - SDEI_LOG("< BIND:%lld\n", ret); + SDEI_LOG("< BIND:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_INTERRUPT_RELEASE: SDEI_LOG("> REL(0x%x)\n", ev_num); ret = sdei_interrupt_release(ev_num); - SDEI_LOG("< REL:%lld\n", ret); + SDEI_LOG("< REL:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_SHARED_RESET: SDEI_LOG("> S_RESET():%lx\n", read_mpidr_el1()); ret = sdei_shared_reset(); - SDEI_LOG("< S_RESET:%lld\n", ret); + SDEI_LOG("< S_RESET:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_PRIVATE_RESET: SDEI_LOG("> P_RESET():%lx\n", read_mpidr_el1()); ret = sdei_private_reset(); - SDEI_LOG("< P_RESET:%lld\n", ret); + SDEI_LOG("< P_RESET:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_ROUTING_SET: - SDEI_LOG("> ROUTE_SET(n:0x%x f:%llx aff:%llx)\n", ev_num, x2, x3); + SDEI_LOG("> ROUTE_SET(n:%d f:%" PRIx64 " aff:%" PRIx64 ")\n", ev_num, x2, x3); ret = sdei_event_routing_set(ev_num, x2, x3); - SDEI_LOG("< ROUTE_SET:%lld\n", ret); + SDEI_LOG("< ROUTE_SET:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_FEATURES: - SDEI_LOG("> FTRS(f:%llx)\n", x1); + SDEI_LOG("> FTRS(f:%" PRIx64 ")\n", x1); ret = (int64_t) sdei_features((unsigned int) x1); - SDEI_LOG("< FTRS:%llx\n", ret); + SDEI_LOG("< FTRS:%" PRIx64 "\n", ret); SMC_RET1(ctx, ret); case SDEI_EVENT_SIGNAL: - SDEI_LOG("> SIGNAL(e:0x%x t:%llx)\n", ev_num, x2); + SDEI_LOG("> SIGNAL(e:%d t:%" PRIx64 ")\n", ev_num, x2); ret = sdei_signal(ev_num, x2); - SDEI_LOG("< SIGNAL:%lld\n", ret); + SDEI_LOG("< SIGNAL:%" PRId64 "\n", ret); SMC_RET1(ctx, ret); default: diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 6de5feb0e..6a7f9c8b6 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include @@ -49,7 +51,7 @@ spmd_spm_core_context_t *spmd_get_context_by_mpidr(uint64_t mpidr) int core_idx = plat_core_pos_by_mpidr(mpidr); if (core_idx < 0) { - ERROR("Invalid mpidr: %llx, returned ID: %d\n", mpidr, core_idx); + ERROR("Invalid mpidr: %" PRIx64 ", returned ID: %d\n", mpidr, core_idx); panic(); } @@ -156,7 +158,7 @@ static int32_t spmd_init(void) rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { - ERROR("SPMC initialisation failed 0x%llx\n", rc); + ERROR("SPMC initialisation failed 0x%" PRIx64 "\n", rc); return 0; } @@ -436,12 +438,12 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, /* Determine which security state this SMC originated from */ secure_origin = is_caller_secure(flags); - VERBOSE("SPM(%u): 0x%x 0x%llx 0x%llx 0x%llx 0x%llx " - "0x%llx 0x%llx 0x%llx\n", - linear_id, smc_fid, x1, x2, x3, x4, - SMC_GET_GP(handle, CTX_GPREG_X5), - SMC_GET_GP(handle, CTX_GPREG_X6), - SMC_GET_GP(handle, CTX_GPREG_X7)); + VERBOSE("SPM(%u): 0x%x 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 + " 0x%" PRIx64 " 0x%" PRIx64 " 0x%" PRIx64 "\n", + linear_id, smc_fid, x1, x2, x3, x4, + SMC_GET_GP(handle, CTX_GPREG_X5), + SMC_GET_GP(handle, CTX_GPREG_X6), + SMC_GET_GP(handle, CTX_GPREG_X7)); switch (smc_fid) { case FFA_ERROR: diff --git a/services/std_svc/spmd/spmd_pm.c b/services/std_svc/spmd/spmd_pm.c index ac962eaa2..6ebafcaa7 100644 --- a/services/std_svc/spmd/spmd_pm.c +++ b/services/std_svc/spmd/spmd_pm.c @@ -6,6 +6,9 @@ #include #include +#include +#include + #include #include #include "spmd_private.h" @@ -110,7 +113,7 @@ static void spmd_cpu_on_finish_handler(u_register_t unused) rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { - ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, + ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id); ctx->state = SPMC_STATE_OFF; return; @@ -138,7 +141,7 @@ static int32_t spmd_cpu_off_handler(u_register_t unused) rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { - ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id); + ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id); } /* Expect a direct message response from the SPMC. */ -- cgit v1.2.3 From 51d8d1e326e39c83e49a0f4c4c269db74fcda226 Mon Sep 17 00:00:00 2001 From: Mark Dykes Date: Mon, 8 Nov 2021 10:36:53 -0600 Subject: Changing SMC code for transitioning Granule Changing the SMC code value to conform with RMM for transitioning a realm granule back to non-secure, otherwise known as undelegate. Signed-off-by: Mark Dykes Change-Id: Ia45ad6cab538de48c65b071b49e504be234afa2b --- include/services/rmi_svc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/services/rmi_svc.h b/include/services/rmi_svc.h index 9106f088d..22f635bab 100644 --- a/include/services/rmi_svc.h +++ b/include/services/rmi_svc.h @@ -45,7 +45,7 @@ #define RMI_FNUM_VERSION_REQ U(0x00) #define RMI_FNUM_GRAN_NS_REALM U(0x01) -#define RMI_FNUM_GRAN_REALM_NS U(0x10) +#define RMI_FNUM_GRAN_REALM_NS U(0x02) /* RMI SMC64 FIDs handled by the RMMD */ #define RMI_RMM_REQ_COMPLETE RMI_FID(SMC_64, RMI_FNUM_REQ_COMPLETE) -- cgit v1.2.3 From 0c23e6f44d41593b6e7f97594c12b5791bd75189 Mon Sep 17 00:00:00 2001 From: Olivier Deprez Date: Tue, 9 Nov 2021 12:37:20 +0100 Subject: fix(spmd): error macro to use correct print format Following merge of [1] then [2] broke the build because of an incorrect format specifier in an ERROR macro. Fix to use the correct print format. [1] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/5437 [2] https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/9211 Signed-off-by: Olivier Deprez Change-Id: I14d4c31091f6a5f4c3252f6d810e9d2bb2f545c4 --- services/std_svc/spmd/spmd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 1390d88c1..f5de54966 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -212,7 +212,7 @@ static uint64_t spmd_secure_interrupt_handler(uint32_t id, rc = spmd_spm_core_sync_entry(ctx); if (rc != 0ULL) { - ERROR("%s failed (%llu) on CPU%u\n", __func__, rc, linear_id); + ERROR("%s failed (%" PRId64 ") on CPU%u\n", __func__, rc, linear_id); } ctx->secure_interrupt_ongoing = false; -- cgit v1.2.3 From 2461bd3a89f7f2cdf4a7302536746733970cfe53 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Tue, 9 Nov 2021 20:49:56 +0000 Subject: fix(gpt_rme): use correct print format for uint64_t sha 4ce3e99a3 introduced printf format specifiers for fixed width types, which uses PRI*64 instead of "ll" for 64 bit values. Signed-off-by: Manish Pandey Change-Id: I30472411467061d58cc6ee22407ed3bad2552751 --- lib/gpt_rme/gpt_rme.c | 13 +++++++------ services/std_svc/rmmd/rmmd_main.c | 8 +++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c index 6d1ff4dac..e424fe239 100644 --- a/lib/gpt_rme/gpt_rme.c +++ b/lib/gpt_rme/gpt_rme.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -445,7 +446,7 @@ static void gpt_generate_l0_blk_desc(pas_region_t *pas) /* Generate the needed block descriptors. */ for (; idx < end_idx; idx++) { l0_gpt_arr[idx] = gpt_desc; - VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%llx (0x%llx)\n", + VERBOSE("[GPT] L0 entry (BLOCK) index %u [%p]: GPI = 0x%" PRIx64 " (0x%" PRIx64 ")\n", idx, &l0_gpt_arr[idx], (gpt_desc >> GPT_L0_BLK_DESC_GPI_SHIFT) & GPT_L0_BLK_DESC_GPI_MASK, l0_gpt_arr[idx]); @@ -606,7 +607,7 @@ static void gpt_generate_l0_tbl_desc(pas_region_t *pas) l0_gpt_base[l0_idx] = GPT_L0_TBL_DESC(l1_gpt_arr); } - VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%llx)\n", + VERBOSE("[GPT] L0 entry (TABLE) index %u [%p] ==> L1 Addr 0x%llx (0x%" PRIx64 ")\n", l0_idx, &l0_gpt_base[l0_idx], (unsigned long long)(l1_gpt_arr), l0_gpt_base[l0_idx]); @@ -1042,7 +1043,7 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, /* Check for address range overflow. */ if ((ULONG_MAX - base) < size) { VERBOSE("[GPT] Transition request address overflow!\n"); - VERBOSE(" Base=0x%llx\n", base); + VERBOSE(" Base=0x%" PRIx64 "\n", base); VERBOSE(" Size=0x%lx\n", size); return -EINVAL; } @@ -1053,7 +1054,7 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, (size == 0U) || ((base + size) >= GPT_PPS_ACTUAL_SIZE(gpt_config.t))) { VERBOSE("[GPT] Invalid granule transition address range!\n"); - VERBOSE(" Base=0x%llx\n", base); + VERBOSE(" Base=0x%" PRIx64 "\n", base); VERBOSE(" Size=0x%lx\n", size); return -EINVAL; } @@ -1072,7 +1073,7 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, gpt_l0_desc = gpt_l0_base[GPT_L0_IDX(base)]; if (GPT_L0_TYPE(gpt_l0_desc) != GPT_L0_TYPE_TBL_DESC) { VERBOSE("[GPT] Granule is not covered by a table descriptor!\n"); - VERBOSE(" Base=0x%llx\n", base); + VERBOSE(" Base=0x%" PRIx64 "\n", base); return -EINVAL; } @@ -1116,7 +1117,7 @@ int gpt_transition_pas(uint64_t base, size_t size, unsigned int src_sec_state, * The isb() will be done as part of context * synchronization when returning to lower EL */ - VERBOSE("[GPT] Granule 0x%llx, GPI 0x%x->0x%x\n", base, gpi, + VERBOSE("[GPT] Granule 0x%" PRIx64 ", GPI 0x%x->0x%x\n", base, gpi, target_pas); return 0; diff --git a/services/std_svc/rmmd/rmmd_main.c b/services/std_svc/rmmd/rmmd_main.c index dacd15087..7f85b636f 100644 --- a/services/std_svc/rmmd/rmmd_main.c +++ b/services/std_svc/rmmd/rmmd_main.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include @@ -131,7 +133,7 @@ static int32_t rmm_init(void) rc = rmmd_rmm_sync_entry(ctx); if (rc != 0ULL) { - ERROR("RMM initialisation failed 0x%llx\n", rc); + ERROR("RMM initialisation failed 0x%" PRIx64 "\n", rc); panic(); } @@ -301,12 +303,12 @@ static int gtsi_transition_granule(uint64_t pa, /* Convert TF-A error codes into GTSI error codes */ if (ret == -EINVAL) { ERROR("[GTSI] Transition failed: invalid %s\n", "address"); - ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa, + ERROR(" PA: 0x%" PRIx64 ", SRC: %d, PAS: %d\n", pa, src_sec_state, target_pas); ret = GRAN_TRANS_RET_BAD_ADDR; } else if (ret == -EPERM) { ERROR("[GTSI] Transition failed: invalid %s\n", "caller/PAS"); - ERROR(" PA: 0x%llx, SRC: %d, PAS: %d\n", pa, + ERROR(" PA: 0x%" PRIx64 ", SRC: %d, PAS: %d\n", pa, src_sec_state, target_pas); ret = GRAN_TRANS_RET_BAD_PAS; } -- cgit v1.2.3 From 52558e080d56a619a1477b19e33f88b754bb93a6 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 23 Sep 2021 14:29:05 -0500 Subject: docs(spm): secure interrupt management in SPMC Change-Id: I9bed67e4146ae92123ab925334e37fb0d3677ef1 Signed-off-by: Madhukar Pappireddy --- docs/components/secure-partition-manager.rst | 152 ++++++++++++++++++++- .../diagrams/ffa-secure-interrupt-handling-nwd.png | Bin 0 -> 48073 bytes .../diagrams/ffa-secure-interrupt-handling-swd.png | Bin 0 -> 48364 bytes 3 files changed, 148 insertions(+), 4 deletions(-) create mode 100755 docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png create mode 100755 docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index fa51fe026..057226181 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -776,11 +776,155 @@ by the SPMC: .. image:: ../resources/diagrams/ffa-ns-interrupt-handling-sp-preemption.png Secure interrupt handling -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- + +This section documents the support implemented for secure interrupt handling in +SPMC as per the guidance provided by FF-A v1.1 Beta0 specification. +The following assumptions are made about the system configuration: + + - In the current implementation, S-EL1 SPs are expected to use the para + virtualized ABIs for interrupt management rather than accessing virtual GIC + interface. + - Unless explicitly stated otherwise, this support is applicable only for + S-EL1 SPs managed by SPMC. + - Secure interrupts are configured as G1S or G0 interrupts. + - All physical interrupts are routed to SPMC when running a secure partition + execution context. + +A physical secure interrupt could preempt normal world execution. Moreover, when +the execution is in secure world, it is highly likely that the target of a +secure interrupt is not the currently running execution context of an SP. It +could be targeted to another FF-A component. Consequently, secure interrupt +management depends on the state of the target execution context of the SP that +is responsible for handling the interrupt. Hence, the spec provides guidance on +how to signal start and completion of secure interrupt handling as discussed in +further sections. + +Secure interrupt signaling mechanisms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Signaling refers to the mechanisms used by SPMC to indicate to the SP execution +context that it has a pending virtual interrupt and to further run the SP +execution context, such that it can handle the virtual interrupt. SPMC uses +either the FFA_INTERRUPT interface with ERET conduit or vIRQ signal for signaling +to S-EL1 SPs. When normal world execution is preempted by a secure interrupt, +the SPMD uses the FFA_INTERRUPT ABI with ERET conduit to signal interrupt to SPMC +running in S-EL2. + ++-----------+---------+---------------+---------------------------------------+ +| SP State | Conduit | Interface and | Description | +| | | parameters | | ++-----------+---------+---------------+---------------------------------------+ +| WAITING | ERET, | FFA_INTERRUPT,| SPMC signals to SP the ID of pending | +| | vIRQ | Interrupt ID | interrupt. It pends vIRQ signal and | +| | | | resumes execution context of SP | +| | | | through ERET. | ++-----------+---------+---------------+---------------------------------------+ +| BLOCKED | ERET, | FFA_INTERRUPT | SPMC signals to SP that an interrupt | +| | vIRQ | | is pending. It pends vIRQ signal and | +| | | | resumes execution context of SP | +| | | | through ERET. | ++-----------+---------+---------------+---------------------------------------+ +| PREEMPTED | vIRQ | NA | SPMC pends the vIRQ signal but does | +| | | | not resume execution context of SP. | ++-----------+---------+---------------+---------------------------------------+ +| RUNNING | ERET, | NA | SPMC pends the vIRQ signal and resumes| +| | vIRQ | | execution context of SP through ERET. | ++-----------+---------+---------------+---------------------------------------+ + +Secure interrupt completion mechanisms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A SP signals secure interrupt handling completion to the SPMC through the +following mechanisms: + + - ``FFA_MSG_WAIT`` ABI if it was in WAITING state. + - ``FFA_RUN`` ABI if its was in BLOCKED state. + +In the current implementation, S-EL1 SPs use para-virtualized HVC interface +implemented by SPMC to perform priority drop and interrupt deactivation (we +assume EOImode = 0, i.e. priority drop and deactivation are done together). + +If normal world execution was preempted by secure interrupt, SPMC uses +FFA_NORMAL_WORLD_RESUME ABI to indicate completion of secure interrupt handling +and further return execution to normal world. If the current SP execution +context was preempted by a secure interrupt to be handled by execution context +of target SP, SPMC resumes current SP after signal completion by target SP +execution context. + +An action is broadly a set of steps taken by the SPMC in response to a physical +interrupt. In order to simplify the design, the current version of secure +interrupt management support in SPMC (Hafnium) does not fully implement the +Scheduling models and Partition runtime models. However, the current +implementation loosely maps to the following actions that are legally allowed +by the specification. Please refer to the Table 8.4 in the spec for further +description of actions. The action specified for a type of interrupt when the +SP is in the message processing running state cannot be less permissive than the +action specified for the same type of interrupt when the SP is in the interrupt +handling running state. + ++--------------------+--------------------+------------+-------------+ +| Runtime Model | NS-Int | Self S-Int | Other S-Int | ++--------------------+--------------------+------------+-------------+ +| Message Processing | Signalable with ME | Signalable | Signalable | ++--------------------+--------------------+------------+-------------+ +| Interrupt Handling | Queued | Queued | Queued | ++--------------------+--------------------+------------+-------------+ + +Abbreviations: + + - NS-Int: A Non-secure physical interrupt. It requires a switch to the Normal + world to be handled. + - Other S-Int: A secure physical interrupt targeted to an SP different from + the one that is currently running. + - Self S-Int: A secure physical interrupt targeted to the SP that is currently + running. + +The following figure describes interrupt handling flow when secure interrupt +triggers while in normal world: + +.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-nwd.png + +A brief description of the events: + + - 1) Secure interrupt triggers while normal world is running. + - 2) FIQ gets trapped to EL3. + - 3) SPMD signals secure interrupt to SPMC at S-EL2 using FFA_INTERRUPT ABI. + - 4) SPMC identifies target vCPU of SP and injects virtual interrupt (pends + vIRQ). + - 5) Since SP1 vCPU is in WAITING state, SPMC signals using FFA_INTERRUPT with + interrupt id as argument and resume it using ERET. + - 6) Execution traps to vIRQ handler in SP1 provided that interrupt is not + masked i.e., PSTATE.I = 0 + - 7) SP1 services the interrupt and invokes the de-activation HVC call. + - 8) SPMC does internal state management and further de-activates the physical + interrupt and resumes SP vCPU. + - 9) SP performs secure interrupt completion through FFA_MSG_WAIT ABI. + - 10) SPMC returns control to EL3 using FFA_NORMAL_WORLD_RESUME. + - 11) EL3 resumes normal world execution. + +The following figure describes interrupt handling flow when secure interrupt +triggers while in secure world: + +.. image:: ../resources/diagrams/ffa-secure-interrupt-handling-swd.png + +A brief description of the events: + + - 1) Secure interrupt triggers while SP2 is running and SP1 is blocked. + - 2) Gets trapped to SPMC as IRQ. + - 3) SPMC finds the target vCPU of secure partition responsible for handling + this secure interrupt. In this scenario, it is SP1. + - 4) SPMC pends vIRQ for SP1 and signals through FFA_INTERRUPT interface. + SPMC further resumes SP1 through ERET conduit. + - 5) Execution traps to vIRQ handler in SP1 provided that interrupt is not + masked i.e., PSTATE.I = 0 + - 6) SP1 services the secure interrupt and invokes the de-activation HVC call. + - 7) SPMC does internal state management, de-activates the physical interrupt + and resumes SP1 vCPU. + - 8) Assuming SP1 is in BLOCKED state, SP1 performs secure interrupt completion + through FFA_RUN ABI. + - 9) SPMC resumes the pre-empted vCPU of SP2. -The current implementation does not support handling of secure interrupts -trapped by the SPMC at S-EL2. This is work in progress planned for future -releases. Power management ---------------- diff --git a/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png b/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png new file mode 100755 index 000000000..c3186107b Binary files /dev/null and b/docs/resources/diagrams/ffa-secure-interrupt-handling-nwd.png differ diff --git a/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png b/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png new file mode 100755 index 000000000..b62000d63 Binary files /dev/null and b/docs/resources/diagrams/ffa-secure-interrupt-handling-swd.png differ -- cgit v1.2.3 From 964ee4e6be70ef638d6c875a761ab5ca359d84fe Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Thu, 11 Nov 2021 11:32:53 -0600 Subject: fix(mt8195): use correct print format for uint64_t sha 4ce3e99a3 introduced printf format specifiers for fixed width types, which uses PRI*64 instead of "ll" for 64 bit variables. Change-Id: I09a8d174694d4b170a6ef2e4a03df13adc829c00 Signed-off-by: Madhukar Pappireddy --- plat/mediatek/mt8195/drivers/dp/mt_dp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plat/mediatek/mt8195/drivers/dp/mt_dp.c b/plat/mediatek/mt8195/drivers/dp/mt_dp.c index 7ab219468..5930cd553 100644 --- a/plat/mediatek/mt8195/drivers/dp/mt_dp.c +++ b/plat/mediatek/mt8195/drivers/dp/mt_dp.c @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: BSD-3-Clause */ + +#include + #include #include #include @@ -28,7 +31,7 @@ int32_t dp_secure_handler(uint64_t cmd, uint64_t para, uint32_t *val) uint32_t fldmask = 0UL; if ((cmd > DP_ATF_CMD_COUNT) || (val == NULL)) { - INFO("dp_secure_handler error cmd 0x%llx\n", cmd); + INFO("dp_secure_handler error cmd 0x%" PRIx64 "\n", cmd); return MTK_SIP_E_INVALID_PARAM; } -- cgit v1.2.3 From 4ef449c15a4055d92632cb7e72267f525a7e2fca Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Fri, 12 Nov 2021 12:59:09 +0000 Subject: fix: use correct printf format for uint64_t sha 4ce3e99a3 introduced printf format specifiers for fixed width types, which uses PRI*64 instead of "ll" for 64 bit values. Signed-off-by: Manish Pandey Change-Id: Ic6811cc1788c698adde0807e5f8ab5290a900a26 --- bl32/tsp/tsp_interrupt.c | 3 ++- drivers/partition/partition.c | 3 ++- drivers/st/spi/stm32_qspi.c | 3 ++- plat/brcm/board/common/board_arm_trusted_boot.c | 3 ++- plat/brcm/board/stingray/src/brcm_pm_ops.c | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bl32/tsp/tsp_interrupt.c b/bl32/tsp/tsp_interrupt.c index 4e500b3ca..430b5ddb8 100644 --- a/bl32/tsp/tsp_interrupt.c +++ b/bl32/tsp/tsp_interrupt.c @@ -5,6 +5,7 @@ */ #include +#include #include @@ -36,7 +37,7 @@ void tsp_update_sync_sel1_intr_stats(uint32_t type, uint64_t elr_el3) #if LOG_LEVEL >= LOG_LEVEL_VERBOSE spin_lock(&console_lock); - VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%llx\n", + VERBOSE("TSP: cpu 0x%lx sync s-el1 interrupt request from 0x%" PRIx64 "\n", read_mpidr(), elr_el3); VERBOSE("TSP: cpu 0x%lx: %d sync s-el1 interrupt requests," " %d sync s-el1 interrupt returns\n", diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c index 68133eaf4..fdea10dbd 100644 --- a/drivers/partition/partition.c +++ b/drivers/partition/partition.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -31,7 +32,7 @@ static void dump_entries(int num) name[len + j] = ' '; } name[EFI_NAMELEN - 1] = '\0'; - VERBOSE("%d: %s %llx-%llx\n", i + 1, name, list.list[i].start, + VERBOSE("%d: %s %" PRIx64 "-%" PRIx64 "\n", i + 1, name, list.list[i].start, list.list[i].start + list.list[i].length - 4); } } diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c index d67f8313f..4b1a0296c 100644 --- a/drivers/st/spi/stm32_qspi.c +++ b/drivers/st/spi/stm32_qspi.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ +#include #include #include @@ -244,7 +245,7 @@ static int stm32_qspi_exec_op(const struct spi_mem_op *op) uint8_t mode = QSPI_CCR_IND_WRITE; int ret; - VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%llx len:%x\n", + VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%" PRIx64 " len:%x\n", __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth, op->data.buswidth, op->addr.val, op->data.nbytes); diff --git a/plat/brcm/board/common/board_arm_trusted_boot.c b/plat/brcm/board/common/board_arm_trusted_boot.c index 7a4dad013..da18c31d0 100644 --- a/plat/brcm/board/common/board_arm_trusted_boot.c +++ b/plat/brcm/board/common/board_arm_trusted_boot.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -344,7 +345,7 @@ void sotp_dump_rows(uint32_t start_row, uint32_t end_row) for (rownum = start_row; rownum <= end_row; rownum++) { rowdata = sotp_mem_read(rownum, SOTP_ROW_NO_ECC); - INFO("%d 0x%llx\n", rownum, rowdata); + INFO("%d 0x%" PRIx64 "\n", rownum, rowdata); } } #endif diff --git a/plat/brcm/board/stingray/src/brcm_pm_ops.c b/plat/brcm/board/stingray/src/brcm_pm_ops.c index 03a604c15..5e07fac08 100644 --- a/plat/brcm/board/stingray/src/brcm_pm_ops.c +++ b/plat/brcm/board/stingray/src/brcm_pm_ops.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -119,7 +120,7 @@ static void brcm_power_down_common(void) standbywfil2 = CDRU_PROC_EVENT_CLEAR__IH3_CDRU_STANDBYWFIL2; break; default: - ERROR("Invalid cluster #%llx\n", MPIDR_AFFLVL1_VAL(mpidr)); + ERROR("Invalid cluster #%" PRIx64 "\n", MPIDR_AFFLVL1_VAL(mpidr)); return; } /* Clear the WFI status bit */ -- cgit v1.2.3 From dc78e62d80e64bf4fe5d5bf4844a7bd1696b7c92 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Thu, 8 Jul 2021 14:14:00 -0500 Subject: feat(sme): enable SME functionality This patch adds two new compile time options to enable SME in TF-A: ENABLE_SME_FOR_NS and ENABLE_SME_FOR_SWD for use in non-secure and secure worlds respectively. Setting ENABLE_SME_FOR_NS=1 will enable SME for non-secure worlds and trap SME, SVE, and FPU/SIMD instructions in secure context. Setting ENABLE_SME_FOR_SWD=1 will disable these traps, but support for SME context management does not yet exist in SPM so building with SPD=spmd will fail. The existing ENABLE_SVE_FOR_NS and ENABLE_SVE_FOR_SWD options cannot be used with SME as it is a superset of SVE and will enable SVE and FPU/SIMD along with SME. Signed-off-by: John Powell Change-Id: Iaaac9d22fe37b4a92315207891da848a8fd0ed73 --- Makefile | 50 +++++++++++++++ bl31/bl31.mk | 5 ++ docs/getting_started/build-options.rst | 19 +++++- include/arch/aarch64/arch.h | 59 +++++++++++++----- include/arch/aarch64/arch_helpers.h | 3 + include/arch/aarch64/el3_common_macros.S | 3 + include/lib/extensions/sme.h | 27 ++++++++ include/lib/extensions/sve.h | 1 + lib/el3_runtime/aarch64/context_mgmt.c | 50 ++++++++++++--- lib/extensions/sme/sme.c | 103 +++++++++++++++++++++++++++++++ lib/extensions/sve/sve.c | 20 ++++++ make_helpers/defaults.mk | 37 ++++++----- services/std_svc/spmd/spmd.mk | 8 ++- 13 files changed, 337 insertions(+), 48 deletions(-) create mode 100644 include/lib/extensions/sme.h create mode 100644 lib/extensions/sme/sme.c diff --git a/Makefile b/Makefile index 2a1d4d8ef..490529178 100644 --- a/Makefile +++ b/Makefile @@ -777,6 +777,52 @@ ifneq (${DECRYPTION_SUPPORT},none) endif endif +# SME/SVE only supported on AArch64 +ifeq (${ARCH},aarch32) + ifeq (${ENABLE_SME_FOR_NS},1) + $(error "ENABLE_SME_FOR_NS cannot be used with ARCH=aarch32") + endif + ifeq (${ENABLE_SVE_FOR_NS},1) + # Warning instead of error due to CI dependency on this + $(warning "ENABLE_SVE_FOR_NS cannot be used with ARCH=aarch32") + $(warning "Forced ENABLE_SVE_FOR_NS=0") + override ENABLE_SVE_FOR_NS := 0 + endif +endif + +# Ensure ENABLE_RME is not used with SME +ifeq (${ENABLE_RME},1) + ifeq (${ENABLE_SME_FOR_NS},1) + $(error "ENABLE_SME_FOR_NS cannot be used with ENABLE_RME") + endif +endif + +# Secure SME/SVE requires the non-secure component as well +ifeq (${ENABLE_SME_FOR_SWD},1) + ifeq (${ENABLE_SME_FOR_NS},0) + $(error "ENABLE_SME_FOR_SWD requires ENABLE_SME_FOR_NS") + endif +endif +ifeq (${ENABLE_SVE_FOR_SWD},1) + ifeq (${ENABLE_SVE_FOR_NS},0) + $(error "ENABLE_SVE_FOR_SWD requires ENABLE_SVE_FOR_NS") + endif +endif + +# SVE and SME cannot be used with CTX_INCLUDE_FPREGS since secure manager does +# its own context management including FPU registers. +ifeq (${CTX_INCLUDE_FPREGS},1) + ifeq (${ENABLE_SME_FOR_NS},1) + $(error "ENABLE_SME_FOR_NS cannot be used with CTX_INCLUDE_FPREGS") + endif + ifeq (${ENABLE_SVE_FOR_NS},1) + # Warning instead of error due to CI dependency on this + $(warning "ENABLE_SVE_FOR_NS cannot be used with CTX_INCLUDE_FPREGS") + $(warning "Forced ENABLE_SVE_FOR_NS=0") + override ENABLE_SVE_FOR_NS := 0 + endif +endif + ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -941,6 +987,8 @@ $(eval $(call assert_booleans,\ ENABLE_PSCI_STAT \ ENABLE_RME \ ENABLE_RUNTIME_INSTRUMENTATION \ + ENABLE_SME_FOR_NS \ + ENABLE_SME_FOR_SWD \ ENABLE_SPE_FOR_LOWER_ELS \ ENABLE_SVE_FOR_NS \ ENABLE_SVE_FOR_SWD \ @@ -1048,6 +1096,8 @@ $(eval $(call add_defines,\ ENABLE_PSCI_STAT \ ENABLE_RME \ ENABLE_RUNTIME_INSTRUMENTATION \ + ENABLE_SME_FOR_NS \ + ENABLE_SME_FOR_SWD \ ENABLE_SPE_FOR_LOWER_ELS \ ENABLE_SVE_FOR_NS \ ENABLE_SVE_FOR_SWD \ diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 9baa0c27f..e751824bb 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -87,9 +87,14 @@ ifeq (${ENABLE_MPMM},1) BL31_SOURCES += ${MPMM_SOURCES} endif +ifeq (${ENABLE_SME_FOR_NS},1) +BL31_SOURCES += lib/extensions/sme/sme.c +BL31_SOURCES += lib/extensions/sve/sve.c +else ifeq (${ENABLE_SVE_FOR_NS},1) BL31_SOURCES += lib/extensions/sve/sve.c endif +endif ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1) BL31_SOURCES += lib/extensions/mpam/mpam.c diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 04e3c0b38..e7ffd9479 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -299,6 +299,21 @@ Common build options instrumented. Enabling this option enables the ``ENABLE_PMF`` build option as well. Default is 0. +- ``ENABLE_SME_FOR_NS``: Boolean option to enable Scalable Matrix Extension + (SME), SVE, and FPU/SIMD for the non-secure world only. These features share + registers so are enabled together. Using this option without + ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure + world to trap to EL3. SME is an optional architectural feature for AArch64 + and TF-A support is experimental. At this time, this build option cannot be + used on systems that have SPD=spmd or ENABLE_RME, and attempting to build + with these options will fail. Default is 0. + +- ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix + Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS + must also be set to use this. If enabling this, the secure world MUST + handle context switching for SME, SVE, and FPU/SIMD registers to ensure that + no data is leaked to non-secure world. This is experimental. Default is 0. + - ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling extensions. This is an optional architectural feature for AArch64. The default is 1 but is automatically disabled when the target architecture @@ -313,8 +328,8 @@ Common build options which are aliased by the SIMD and FP registers. The build option is not compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to - 1. The default is 1 but is automatically disabled when the target - architecture is AArch32. + 1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1 + since SME encompasses SVE. - ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world. SVE is an optional architectural feature for AArch64. Note that this option diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index 5408acf82..0fb4e7436 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -218,8 +218,8 @@ #define ID_AA64DFR0_MTPMU_SUPPORTED ULL(1) /* ID_AA64ISAR0_EL1 definitions */ -#define ID_AA64ISAR0_RNDR_SHIFT U(60) -#define ID_AA64ISAR0_RNDR_MASK ULL(0xf) +#define ID_AA64ISAR0_RNDR_SHIFT U(60) +#define ID_AA64ISAR0_RNDR_MASK ULL(0xf) /* ID_AA64ISAR1_EL1 definitions */ #define ID_AA64ISAR1_EL1 S3_0_C0_C6_1 @@ -286,10 +286,10 @@ #define ID_AA64MMFR1_EL1_VHE_SHIFT U(8) #define ID_AA64MMFR1_EL1_VHE_MASK ULL(0xf) -#define ID_AA64MMFR1_EL1_HCX_SHIFT U(40) -#define ID_AA64MMFR1_EL1_HCX_MASK ULL(0xf) -#define ID_AA64MMFR1_EL1_HCX_SUPPORTED ULL(0x1) -#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0) +#define ID_AA64MMFR1_EL1_HCX_SHIFT U(40) +#define ID_AA64MMFR1_EL1_HCX_MASK ULL(0xf) +#define ID_AA64MMFR1_EL1_HCX_SUPPORTED ULL(0x1) +#define ID_AA64MMFR1_EL1_HCX_NOT_SUPPORTED ULL(0x0) /* ID_AA64MMFR2_EL1 definitions */ #define ID_AA64MMFR2_EL1 S3_0_C0_C7_2 @@ -329,6 +329,9 @@ #define ID_AA64PFR1_MPAM_FRAC_SHIFT ULL(16) #define ID_AA64PFR1_MPAM_FRAC_MASK ULL(0xf) +#define ID_AA64PFR1_EL1_SME_SHIFT U(24) +#define ID_AA64PFR1_EL1_SME_MASK ULL(0xf) + /* ID_PFR1_EL1 definitions */ #define ID_PFR1_VIRTEXT_SHIFT U(12) #define ID_PFR1_VIRTEXT_MASK U(0xf) @@ -388,6 +391,7 @@ #define SCTLR_ITFSB_BIT (ULL(1) << 37) #define SCTLR_TCF0_SHIFT U(38) #define SCTLR_TCF0_MASK ULL(3) +#define SCTLR_ENTP2_BIT (ULL(1) << 60) /* Tag Check Faults in EL0 have no effect on the PE */ #define SCTLR_TCF0_NO_EFFECT U(0) @@ -442,7 +446,9 @@ #define SCR_GPF_BIT (UL(1) << 48) #define SCR_TWEDEL_SHIFT U(30) #define SCR_TWEDEL_MASK ULL(0xf) -#define SCR_HXEn_BIT (UL(1) << 38) +#define SCR_HXEn_BIT (UL(1) << 38) +#define SCR_ENTP2_SHIFT U(41) +#define SCR_ENTP2_BIT (UL(1) << SCR_ENTP2_SHIFT) #define SCR_AMVOFFEN_BIT (UL(1) << 35) #define SCR_TWEDEn_BIT (UL(1) << 29) #define SCR_ECVEN_BIT (UL(1) << 28) @@ -465,7 +471,7 @@ #define SCR_FIQ_BIT (UL(1) << 2) #define SCR_IRQ_BIT (UL(1) << 1) #define SCR_NS_BIT (UL(1) << 0) -#define SCR_VALID_BIT_MASK U(0x2f8f) +#define SCR_VALID_BIT_MASK U(0x24000002F8F) #define SCR_RESET_VAL SCR_RES1_BITS /* MDCR_EL3 definitions */ @@ -574,23 +580,28 @@ #define TAM_SHIFT U(30) #define TAM_BIT (U(1) << TAM_SHIFT) #define TTA_BIT (U(1) << 20) +#define ESM_BIT (U(1) << 12) #define TFP_BIT (U(1) << 10) #define CPTR_EZ_BIT (U(1) << 8) -#define CPTR_EL3_RESET_VAL (TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT & ~(CPTR_EZ_BIT)) +#define CPTR_EL3_RESET_VAL ((TCPAC_BIT | TAM_BIT | TTA_BIT | TFP_BIT) & \ + ~(CPTR_EZ_BIT | ESM_BIT)) /* CPTR_EL2 definitions */ #define CPTR_EL2_RES1 ((U(1) << 13) | (U(1) << 12) | (U(0x3ff))) #define CPTR_EL2_TCPAC_BIT (U(1) << 31) #define CPTR_EL2_TAM_SHIFT U(30) #define CPTR_EL2_TAM_BIT (U(1) << CPTR_EL2_TAM_SHIFT) +#define CPTR_EL2_SMEN_MASK ULL(0x3) +#define CPTR_EL2_SMEN_SHIFT U(24) #define CPTR_EL2_TTA_BIT (U(1) << 20) +#define CPTR_EL2_TSM_BIT (U(1) << 12) #define CPTR_EL2_TFP_BIT (U(1) << 10) #define CPTR_EL2_TZ_BIT (U(1) << 8) #define CPTR_EL2_RESET_VAL CPTR_EL2_RES1 /* VTCR_EL2 definitions */ -#define VTCR_RESET_VAL U(0x0) -#define VTCR_EL2_MSA (U(1) << 31) +#define VTCR_RESET_VAL U(0x0) +#define VTCR_EL2_MSA (U(1) << 31) /* CPSR/SPSR definitions */ #define DAIF_FIQ_BIT (U(1) << 0) @@ -917,6 +928,20 @@ /* ZCR_EL2 definitions */ #define ZCR_EL2_LEN_MASK U(0xf) +/******************************************************************************* + * Definitions for system register interface to SME as needed in EL3 + ******************************************************************************/ +#define ID_AA64SMFR0_EL1 S3_0_C0_C4_5 +#define SMCR_EL3 S3_6_C1_C2_6 + +/* ID_AA64SMFR0_EL1 definitions */ +#define ID_AA64SMFR0_EL1_FA64_BIT (UL(1) << 63) + +/* SMCR_ELx definitions */ +#define SMCR_ELX_LEN_SHIFT U(0) +#define SMCR_ELX_LEN_MASK U(0x1ff) +#define SMCR_ELX_FA64_BIT (U(1) << 31) + /******************************************************************************* * Definitions of MAIR encodings for device and normal memory ******************************************************************************/ @@ -1199,12 +1224,12 @@ /******************************************************************************* * FEAT_HCX - Extended Hypervisor Configuration Register ******************************************************************************/ -#define HCRX_EL2 S3_4_C1_C2_2 -#define HCRX_EL2_FGTnXS_BIT (UL(1) << 4) -#define HCRX_EL2_FnXS_BIT (UL(1) << 3) -#define HCRX_EL2_EnASR_BIT (UL(1) << 2) -#define HCRX_EL2_EnALS_BIT (UL(1) << 1) -#define HCRX_EL2_EnAS0_BIT (UL(1) << 0) +#define HCRX_EL2 S3_4_C1_C2_2 +#define HCRX_EL2_FGTnXS_BIT (UL(1) << 4) +#define HCRX_EL2_FnXS_BIT (UL(1) << 3) +#define HCRX_EL2_EnASR_BIT (UL(1) << 2) +#define HCRX_EL2_EnALS_BIT (UL(1) << 1) +#define HCRX_EL2_EnAS0_BIT (UL(1) << 0) /******************************************************************************* * Definitions for DynamicIQ Shared Unit registers diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 37fa047c3..733bb23c4 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -509,6 +509,9 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3) DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el2, ZCR_EL2) +DEFINE_RENAME_SYSREG_READ_FUNC(id_aa64smfr0_el1, ID_AA64SMFR0_EL1) +DEFINE_RENAME_SYSREG_RW_FUNCS(smcr_el3, SMCR_EL3) + DEFINE_RENAME_SYSREG_READ_FUNC(erridr_el1, ERRIDR_EL1) DEFINE_RENAME_SYSREG_WRITE_FUNC(errselr_el1, ERRSELR_EL1) diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S index 8e8d33480..f29def7f3 100644 --- a/include/arch/aarch64/el3_common_macros.S +++ b/include/arch/aarch64/el3_common_macros.S @@ -222,6 +222,9 @@ * * CPTR_EL3.EZ: Set to zero so that all SVE functionality is trapped * to EL3 by default. + * + * CPTR_EL3.ESM: Set to zero so that all SME functionality is trapped + * to EL3 by default. */ mov_imm x0, (CPTR_EL3_RESET_VAL & ~(TCPAC_BIT | TTA_BIT | TFP_BIT)) diff --git a/include/lib/extensions/sme.h b/include/lib/extensions/sme.h new file mode 100644 index 000000000..893f9f2cb --- /dev/null +++ b/include/lib/extensions/sme.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SME_H +#define SME_H + +#include + +#include + +/* + * Maximum value of LEN field in SMCR_ELx. This is different than the maximum + * supported value which is platform dependent. In the first version of SME the + * LEN field is limited to 4 bits but will be expanded in future iterations. + * To support different versions, the code that discovers the supported vector + * lengths will write the max value into SMCR_ELx then read it back to see how + * many bits are implemented. + */ +#define SME_SMCR_LEN_MAX U(0x1FF) + +void sme_enable(cpu_context_t *context); +void sme_disable(cpu_context_t *context); + +#endif /* SME_H */ diff --git a/include/lib/extensions/sve.h b/include/lib/extensions/sve.h index c85e08c9f..4b66cdb09 100644 --- a/include/lib/extensions/sve.h +++ b/include/lib/extensions/sve.h @@ -10,5 +10,6 @@ #include void sve_enable(cpu_context_t *context); +void sve_disable(cpu_context_t *context); #endif /* SVE_H */ diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c index 0ec7e7e1c..c69dc952a 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ #include #include -static void enable_extensions_secure(cpu_context_t *ctx); +static void manage_extensions_secure(cpu_context_t *ctx); /******************************************************************************* * Context management library initialisation routine. This library is used by @@ -219,7 +220,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) /* Save the initialized value of CPTR_EL3 register */ write_ctx_reg(get_el3state_ctx(ctx), CTX_CPTR_EL3, read_cptr_el3()); if (security_state == SECURE) { - enable_extensions_secure(ctx); + manage_extensions_secure(ctx); } /* @@ -365,7 +366,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep) * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise * it is zero. ******************************************************************************/ -static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) +static void manage_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) { #if IMAGE_BL31 #if ENABLE_SPE_FOR_LOWER_ELS @@ -376,7 +377,11 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) amu_enable(el2_unused, ctx); #endif -#if ENABLE_SVE_FOR_NS +#if ENABLE_SME_FOR_NS + /* Enable SME, SVE, and FPU/SIMD for non-secure world. */ + sme_enable(ctx); +#elif ENABLE_SVE_FOR_NS + /* Enable SVE and FPU/SIMD for non-secure world. */ sve_enable(ctx); #endif @@ -395,20 +400,45 @@ static void enable_extensions_nonsecure(bool el2_unused, cpu_context_t *ctx) #if ENABLE_TRF_FOR_NS trf_enable(); #endif /* ENABLE_TRF_FOR_NS */ - #endif } /******************************************************************************* * Enable architecture extensions on first entry to Secure world. ******************************************************************************/ -static void enable_extensions_secure(cpu_context_t *ctx) +static void manage_extensions_secure(cpu_context_t *ctx) { #if IMAGE_BL31 -#if ENABLE_SVE_FOR_SWD + #if ENABLE_SME_FOR_NS + #if ENABLE_SME_FOR_SWD + /* + * Enable SME, SVE, FPU/SIMD in secure context, secure manager must + * ensure SME, SVE, and FPU/SIMD context properly managed. + */ + sme_enable(ctx); + #else /* ENABLE_SME_FOR_SWD */ + /* + * Disable SME, SVE, FPU/SIMD in secure context so non-secure world can + * safely use the associated registers. + */ + sme_disable(ctx); + #endif /* ENABLE_SME_FOR_SWD */ + #elif ENABLE_SVE_FOR_NS + #if ENABLE_SVE_FOR_SWD + /* + * Enable SVE and FPU in secure context, secure manager must ensure that + * the SVE and FPU register contexts are properly managed. + */ sve_enable(ctx); -#endif -#endif + #else /* ENABLE_SVE_FOR_SWD */ + /* + * Disable SVE and FPU in secure context so non-secure world can safely + * use them. + */ + sve_disable(ctx); + #endif /* ENABLE_SVE_FOR_SWD */ + #endif /* ENABLE_SVE_FOR_NS */ +#endif /* IMAGE_BL31 */ } /******************************************************************************* @@ -654,7 +684,7 @@ void cm_prepare_el3_exit(uint32_t security_state) write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL & ~(CNTHP_CTL_ENABLE_BIT)); } - enable_extensions_nonsecure(el2_unused, ctx); + manage_extensions_nonsecure(el2_unused, ctx); } cm_el1_sysregs_context_restore(security_state); diff --git a/lib/extensions/sme/sme.c b/lib/extensions/sme/sme.c new file mode 100644 index 000000000..1c2b98448 --- /dev/null +++ b/lib/extensions/sme/sme.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include +#include +#include +#include +#include + +static bool feat_sme_supported(void) +{ + uint64_t features; + + features = read_id_aa64pfr1_el1() >> ID_AA64PFR1_EL1_SME_SHIFT; + return (features & ID_AA64PFR1_EL1_SME_MASK) != 0U; +} + +static bool feat_sme_fa64_supported(void) +{ + uint64_t features; + + features = read_id_aa64smfr0_el1(); + return (features & ID_AA64SMFR0_EL1_FA64_BIT) != 0U; +} + +void sme_enable(cpu_context_t *context) +{ + u_register_t reg; + u_register_t cptr_el3; + el3_state_t *state; + + /* Make sure SME is implemented in hardware before continuing. */ + if (!feat_sme_supported()) { + return; + } + + /* Get the context state. */ + state = get_el3state_ctx(context); + + /* Enable SME in CPTR_EL3. */ + reg = read_ctx_reg(state, CTX_CPTR_EL3); + reg |= ESM_BIT; + write_ctx_reg(state, CTX_CPTR_EL3, reg); + + /* Set the ENTP2 bit in SCR_EL3 to enable access to TPIDR2_EL0. */ + reg = read_ctx_reg(state, CTX_SCR_EL3); + reg |= SCR_ENTP2_BIT; + write_ctx_reg(state, CTX_SCR_EL3, reg); + + /* Set CPTR_EL3.ESM bit so we can write SMCR_EL3 without trapping. */ + cptr_el3 = read_cptr_el3(); + write_cptr_el3(cptr_el3 | ESM_BIT); + + /* + * Set the max LEN value and FA64 bit. This register is set up globally + * to be the least restrictive, then lower ELs can restrict as needed + * using SMCR_EL2 and SMCR_EL1. + */ + reg = SMCR_ELX_LEN_MASK; + if (feat_sme_fa64_supported()) { + VERBOSE("[SME] FA64 enabled\n"); + reg |= SMCR_ELX_FA64_BIT; + } + write_smcr_el3(reg); + + /* Reset CPTR_EL3 value. */ + write_cptr_el3(cptr_el3); + + /* Enable SVE/FPU in addition to SME. */ + sve_enable(context); +} + +void sme_disable(cpu_context_t *context) +{ + u_register_t reg; + el3_state_t *state; + + /* Make sure SME is implemented in hardware before continuing. */ + if (!feat_sme_supported()) { + return; + } + + /* Get the context state. */ + state = get_el3state_ctx(context); + + /* Disable SME, SVE, and FPU since they all share registers. */ + reg = read_ctx_reg(state, CTX_CPTR_EL3); + reg &= ~ESM_BIT; /* Trap SME */ + reg &= ~CPTR_EZ_BIT; /* Trap SVE */ + reg |= TFP_BIT; /* Trap FPU/SIMD */ + write_ctx_reg(state, CTX_CPTR_EL3, reg); + + /* Disable access to TPIDR2_EL0. */ + reg = read_ctx_reg(state, CTX_SCR_EL3); + reg &= ~SCR_ENTP2_BIT; + write_ctx_reg(state, CTX_SCR_EL3, reg); +} diff --git a/lib/extensions/sve/sve.c b/lib/extensions/sve/sve.c index 2702c30f3..aa8904b9b 100644 --- a/lib/extensions/sve/sve.c +++ b/lib/extensions/sve/sve.c @@ -43,3 +43,23 @@ void sve_enable(cpu_context_t *context) write_ctx_reg(get_el3state_ctx(context), CTX_ZCR_EL3, (ZCR_EL3_LEN_MASK & CONVERT_SVE_LENGTH(512))); } + +void sve_disable(cpu_context_t *context) +{ + u_register_t reg; + el3_state_t *state; + + /* Make sure SME is implemented in hardware before continuing. */ + if (!sve_supported()) { + return; + } + + /* Get the context state. */ + state = get_el3state_ctx(context); + + /* Disable SVE and FPU since they share registers. */ + reg = read_ctx_reg(state, CTX_CPTR_EL3); + reg &= ~CPTR_EZ_BIT; /* Trap SVE */ + reg |= TFP_BIT; /* Trap FPU/SIMD */ + write_ctx_reg(state, CTX_CPTR_EL3, reg); +} diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 45f5fa87f..e88148f4e 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -134,7 +134,7 @@ ENABLE_BTI := 0 ENABLE_PAUTH := 0 # Flag to enable access to the HCRX_EL2 register by setting SCR_EL3.HXEn. -ENABLE_FEAT_HCX := 0 +ENABLE_FEAT_HCX := 0 # By default BL31 encryption disabled ENCRYPT_BL31 := 0 @@ -222,13 +222,13 @@ RESET_TO_BL31 := 0 SAVE_KEYS := 0 # Software Delegated Exception support -SDEI_SUPPORT := 0 +SDEI_SUPPORT := 0 # True Random Number firmware Interface -TRNG_SUPPORT := 0 +TRNG_SUPPORT := 0 # SMCCC PCI support -SMC_PCI_SUPPORT := 0 +SMC_PCI_SUPPORT := 0 # Whether code and read-only data should be put on separate memory pages. The # platform Makefile is free to override this value. @@ -303,7 +303,7 @@ ENABLE_SPE_FOR_LOWER_ELS := 1 # SPE is only supported on AArch64 so disable it on AArch32. ifeq (${ARCH},aarch32) - override ENABLE_SPE_FOR_LOWER_ELS := 0 + override ENABLE_SPE_FOR_LOWER_ELS := 0 endif # Include Memory Tagging Extension registers in cpu context. This must be set @@ -316,15 +316,18 @@ ENABLE_AMU_AUXILIARY_COUNTERS := 0 ENABLE_AMU_FCONF := 0 AMU_RESTRICT_COUNTERS := 0 -# By default, enable Scalable Vector Extension if implemented only for Non-secure -# lower ELs -# Note SVE is only supported on AArch64 - therefore do not enable in AArch32 -ifneq (${ARCH},aarch32) - ENABLE_SVE_FOR_NS := 1 - ENABLE_SVE_FOR_SWD := 0 -else - override ENABLE_SVE_FOR_NS := 0 - override ENABLE_SVE_FOR_SWD := 0 +# Enable SVE for non-secure world by default +ENABLE_SVE_FOR_NS := 1 +ENABLE_SVE_FOR_SWD := 0 + +# SME defaults to disabled +ENABLE_SME_FOR_NS := 0 +ENABLE_SME_FOR_SWD := 0 + +# If SME is enabled then force SVE off +ifeq (${ENABLE_SME_FOR_NS},1) + override ENABLE_SVE_FOR_NS := 0 + override ENABLE_SVE_FOR_SWD := 0 endif SANITIZE_UB := off @@ -348,7 +351,7 @@ CTX_INCLUDE_EL2_REGS := 0 SUPPORT_STACK_MEMTAG := no # Select workaround for AT speculative behaviour. -ERRATA_SPECULATIVE_AT := 0 +ERRATA_SPECULATIVE_AT := 0 # Trap RAS error record access from lower EL RAS_TRAP_LOWER_EL_ERR_ACCESS := 0 @@ -379,9 +382,9 @@ PSA_FWU_SUPPORT := 0 # Note FEAT_TRBE is only supported on AArch64 - therefore do not enable in # AArch32. ifneq (${ARCH},aarch32) - ENABLE_TRBE_FOR_NS := 0 + ENABLE_TRBE_FOR_NS := 0 else - override ENABLE_TRBE_FOR_NS := 0 + override ENABLE_TRBE_FOR_NS := 0 endif # By default, disable access of trace system registers from NS lower diff --git a/services/std_svc/spmd/spmd.mk b/services/std_svc/spmd/spmd.mk index 73f7c85dd..8efbdc868 100644 --- a/services/std_svc/spmd/spmd.mk +++ b/services/std_svc/spmd/spmd.mk @@ -1,11 +1,15 @@ # -# Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2021, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # ifneq (${ARCH},aarch64) - $(error "Error: SPMD is only supported on aarch64.") + $(error "Error: SPMD is only supported on aarch64.") +endif + +ifeq (${ENABLE_SME_FOR_NS},1) + $(error "Error: SPMD is not compatible with ENABLE_SME_FOR_NS") endif SPMD_SOURCES += $(addprefix services/std_svc/spmd/, \ -- cgit v1.2.3 From 6ee92598cf540ac5746f8af714aa3601ea03ad3d Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 25 Aug 2021 16:32:23 -0500 Subject: docs(gpt): add documentation page for GPT library This patch adds some documentation for the GPT library as well as adds code owners for it. Signed-off-by: John Powell Change-Id: If1cd79626eadb27e1024d731b26ee2e20af74a66 --- docs/about/maintainers.rst | 19 +- .../granule-protection-tables-design.rst | 235 +++++++++++++++++++++ docs/components/index.rst | 1 + 3 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 docs/components/granule-protection-tables-design.rst diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 337dde617..7a48601b7 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -75,7 +75,7 @@ Software Delegated Exception Interface (SDEI) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :|M|: Mark Dykes :|G|: `mardyk01`_ -:|M|: John Powell +:|M|: John Powell :|G|: `john-powell-arm`_ :|F|: services/std_svc/sdei/ @@ -105,7 +105,7 @@ Exception Handling Framework (EHF) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :|M|: Manish Badarkhe :|G|: `ManishVB-Arm`_ -:|M|: John Powell +:|M|: John Powell :|G|: `john-powell-arm`_ :|F|: bl31/ehf.c @@ -115,7 +115,7 @@ Realm Management Extension (RME) :|G|: `bipinravi-arm`_ :|M|: Mark Dykes :|G|: `mardyk01`_ -:|M|: John Powell +:|M|: John Powell :|G|: `john-powell-arm`_ :|M|: Zelalem Aweke :|G|: `zelalem-aweke`_ @@ -201,7 +201,7 @@ Arm CPU libraries ^^^^^^^^^^^^^^^^^ :|M|: Lauren Wehrmeister :|G|: `laurenw-arm`_ -:|M|: John Powell +:|M|: John Powell :|G|: `john-powell-arm`_ :|F|: lib/cpus/ @@ -255,7 +255,7 @@ Standard C library ^^^^^^^^^^^^^^^^^^ :|M|: Alexei Fedorov :|G|: `AlexeiFedorov`_ -:|M|: John Powell +:|M|: John Powell :|G|: `john-powell-arm`_ :|F|: lib/libc/ @@ -335,6 +335,15 @@ Max Power Mitigation Mechanism (MPMM) :|F|: include/lib/mpmm/ :|F|: lib/mpmm/ +Granule Protection Tables Library (GPT-RME) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:|M|: Mark Dykes +:|G|: `mardyk01`_ +:|M|: John Powell +:|G|: `john-powell-arm`_ +:|F|: lib/gpt_rme +:|F|: include/lib/gpt_rme + Platform Ports ~~~~~~~~~~~~~~ diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst new file mode 100644 index 000000000..07637dd58 --- /dev/null +++ b/docs/components/granule-protection-tables-design.rst @@ -0,0 +1,235 @@ +Granule Protection Tables Library +================================= + +This document describes the design of the granule protection tables (GPT) +library used by Trusted Firmware-A (TF-A). This library provides the APIs needed +to initialize the GPTs based on a data structure containing information about +the systems memory layout, configure the system registers to enable granule +protection checks based on these tables, and transition granules between +different PAS (physical address spaces) at runtime. + +Arm CCA adds two new security states for a total of four: root, realm, secure, and +non-secure. In addition to new security states, corresponding physical address +spaces have been added to control memory access for each state. The PAS access +allowed to each security state can be seen in the table below. + +.. list-table:: Security states and PAS access rights + :widths: 25 25 25 25 25 + :header-rows: 1 + + * - + - Root state + - Realm state + - Secure state + - Non-secure state + * - Root PAS + - yes + - no + - no + - no + * - Realm PAS + - yes + - yes + - no + - no + * - Secure PAS + - yes + - no + - yes + - no + * - Non-secure PAS + - yes + - yes + - yes + - yes + +The GPT can function as either a 1 level or 2 level lookup depending on how a +PAS region is configured. The first step is the level 0 table, each entry in the +level 0 table controls access to a relatively large region in memory (block +descriptor), and the entire region can belong to a single PAS when a one step +mapping is used, or a level 0 entry can link to a level 1 table where relatively +small regions (granules) of memory can be assigned to different PAS with a 2 +step mapping. The type of mapping used for each PAS is determined by the user +when setting up the configuration structure. + +Design Concepts and Interfaces +------------------------------ + +This section covers some important concepts and data structures used in the GPT +library. + +There are three main parameters that determine how the tables are organized and +function: the PPS (protected physical space) which is the total amount of +protected physical address space in the system, PGS (physical granule size) +which is how large each level 1 granule is, and L0GPTSZ (level 0 GPT size) which +determines how much physical memory is governed by each level 0 entry. A granule +is the smallest unit of memory that can be independently assigned to a PAS. + +L0GPTSZ is determined by the hardware and is read from the GPCCR_EL3 register. +PPS and PGS are passed into the APIs at runtime and can be determined in +whatever way is best for a given platform, either through some algorithm or hard +coded in the firmware. + +GPT setup is split into two parts: table creation and runtime initialization. In +the table creation step, a data structure containing information about the +desired PAS regions is passed into the library which validates the mappings, +creates the tables in memory, and enables granule protection checks. In the +runtime initialization step, the runtime firmware locates the existing tables in +memory using the GPT register configuration and saves important data to a +structure used by the granule transition service which will be covered more +below. + +In the reference implementation for FVP models, you can find an example of PAS +region definitions in the file ``include/plat/arm/common/arm_pas_def.h``. Table +creation API calls can be found in ``plat/arm/common/arm_bl2_setup.c`` and +runtime initialization API calls can be seen in +``plat/arm/common/arm_bl31_setup.c``. + +Defining PAS regions +~~~~~~~~~~~~~~~~~~~~ + +A ``pas_region_t`` structure is a way to represent a physical address space and +its attributes that can be used by the GPT library to initialize the tables. + +This structure is composed of the following: + +#. The base physical address +#. The region size +#. The desired attributes of this memory region (mapping type, PAS type) + +See the ``pas_region_t`` type in ``include/lib/gpt_rme/gpt_rme.h``. + +The programmer should provide the API with an array containing ``pas_region_t`` +structures, then the library will check the desired memory access layout for +validity and create tables to implement it. + +``pas_region_t`` is a public type, however it is recommended that the macros +``GPT_MAP_REGION_BLOCK`` and ``GPT_MAP_REGION_GRANULE`` be used to populate +these structures instead of doing it manually to reduce the risk of future +compatibility issues. These macros take the base physical address, region size, +and PAS type as arguments to generate the pas_region_t structure. As the names +imply, ``GPT_MAP_REGION_BLOCK`` creates a region using only L0 mapping while +``GPT_MAP_REGION_GRANULE`` creates a region using L0 and L1 mappings. + +Level 0 and Level 1 Tables +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The GPT initialization APIs require memory to be passed in for the tables to be +constructed, ``gpt_init_l0_tables`` takes a memory address and size for building +the level 0 tables and ``gpt_init_pas_l1_tables`` takes an address and size for +building the level 1 tables which are linked from level 0 descriptors. The +tables should have PAS type ``GPT_GPI_ROOT`` and a typical system might place +its level 0 table in SRAM and its level 1 table(s) in DRAM. + +Granule Transition Service +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Granule Transition Service allows memory mapped with GPT_MAP_REGION_GRANULE +ownership to be changed using SMC calls. Non-secure granules can be transitioned +to either realm or secure space, and realm and secure granules can be +transitioned back to non-secure. This library only allows memory mapped as +granules to be transitioned, memory mapped as blocks have their GPIs fixed after +table creation. + +Library APIs +------------ + +The public APIs and types can be found in ``include/lib/gpt_rme/gpt_rme.h`` and this +section is intended to provide additional details and clarifications. + +To create the GPTs and enable granule protection checks the APIs need to be +called in the correct order and at the correct time during the system boot +process. + +#. Firmware must enable the MMU. +#. Firmware must call ``gpt_init_l0_tables`` to initialize the level 0 tables to + a default state, that is, initializing all of the L0 descriptors to allow all + accesses to all memory. The PPS is provided to this function as an argument. +#. DDR discovery and initialization by the system, the discovered DDR region(s) + are then added to the L1 PAS regions to be initialized in the next step and + used by the GTSI at runtime. +#. Firmware must call ``gpt_init_pas_l1_tables`` with a pointer to an array of + ``pas_region_t`` structures containing the desired memory access layout. The + PGS is provided to this function as an argument. +#. Firmware must call ``gpt_enable`` to enable granule protection checks by + setting the correct register values. +#. In systems that make use of the granule transition service, runtime + firmware must call ``gpt_runtime_init`` to set up the data structures needed + by the GTSI to find the tables and transition granules between PAS types. + +API Constraints +~~~~~~~~~~~~~~~ + +The values allowed by the API for PPS and PGS are enumerated types +defined in the file ``include/lib/gpt_rme/gpt_rme.h``. + +Allowable values for PPS along with their corresponding size. + +* ``GPCCR_PPS_4GB`` (4GB protected space, 0x100000000 bytes) +* ``GPCCR_PPS_64GB`` (64GB protected space, 0x1000000000 bytes) +* ``GPCCR_PPS_1TB`` (1TB protected space, 0x10000000000 bytes) +* ``GPCCR_PPS_4TB`` (4TB protected space, 0x40000000000 bytes) +* ``GPCCR_PPS_16TB`` (16TB protected space, 0x100000000000 bytes) +* ``GPCCR_PPS_256TB`` (256TB protected space, 0x1000000000000 bytes) +* ``GPCCR_PPS_4PB`` (4PB protected space, 0x10000000000000 bytes) + +Allowable values for PGS along with their corresponding size. + +* ``GPCCR_PGS_4K`` (4KB granules, 0x1000 bytes) +* ``GPCCR_PGS_16K`` (16KB granules, 0x4000 bytes) +* ``GPCCR_PGS_64K`` (64KB granules, 0x10000 bytes) + +Allowable values for L0GPTSZ along with the corresponding size. + +* ``GPCCR_L0GPTSZ_30BITS`` (1GB regions, 0x40000000 bytes) +* ``GPCCR_L0GPTSZ_34BITS`` (16GB regions, 0x400000000 bytes) +* ``GPCCR_L0GPTSZ_36BITS`` (64GB regions, 0x1000000000 bytes) +* ``GPCCR_L0GPTSZ_39BITS`` (512GB regions, 0x8000000000 bytes) + +Note that the value of the PPS, PGS, and L0GPTSZ definitions is an encoded value +corresponding to the size, not the size itself. The decoded hex representations +of the sizes have been provided for convenience. + +The L0 table memory has some constraints that must be taken into account. + +* The L0 table must be aligned to either the table size or 4096 bytes, whichever + is greater. L0 table size is the total protected space (PPS) divided by the + size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor + (8 bytes). ((PPS / L0GPTSZ) * 8) +* The L0 memory size must be greater than or equal to the table size. +* The L0 memory must fall within a PAS of type GPT_GPI_ROOT. + +The L1 memory also has some constraints. + +* The L1 tables must be aligned to their size. The size of each L1 table is the + size of each L0 region (L0GPTSZ) divided by the granule size (PGS) divided by + the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2) +* There must be enough L1 memory supplied to build all requested L1 tables. +* The L1 memory must fall within a PAS of type GPT_GPI_ROOT. + +If an invalid combination of parameters is supplied, the APIs will print an +error message and return a negative value. The return values of APIs should be +checked to ensure successful configuration. + +Sample Calculation for L0 memory size and alignment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let PPS=GPCCR_PPS_4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS + +We can find the total L0 table size with ((PPS / L0GPTSZ) * 8) + +Substitute values to get this: ((0x100000000 / 0x40000000) * 8) + +And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0 +tables must be aligned to 4096 bytes. + +Sample calculation for L1 table size and alignment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let PGS=GPCCR_PGS_4K and L0GPTSZ=GPCCR_L0GPTSZ_30BITS + +We can find the size of each L1 table with ((L0GPTSZ / PGS) / 2). + +Substitute values: ((0x40000000 / 0x1000) / 2) + +And solve to get 0x20000 bytes per L1 table. diff --git a/docs/components/index.rst b/docs/components/index.rst index 754526daf..95fe42cff 100644 --- a/docs/components/index.rst +++ b/docs/components/index.rst @@ -25,3 +25,4 @@ Components xlat-tables-lib-v2-design cot-binding realm-management-extension + granule-protection-tables-design -- cgit v1.2.3 From 7446c266c91bc28c87fca634df57bdcf15b32a5b Mon Sep 17 00:00:00 2001 From: Zelalem Aweke Date: Thu, 21 Oct 2021 13:59:45 -0500 Subject: docs(rme): add description of TF-A changes for RME This patch expands the RME documentation with description of TF-A changes for RME. It also modifies some other parts of TF-A documentation to account for RME changes. Signed-off-by: Zelalem Aweke Change-Id: I9e6feeee235f0ba4b767d239f15840f1e0c540bb --- docs/components/realm-management-extension.rst | 89 +++++++++++++++++++--- docs/design/firmware-design.rst | 10 ++- docs/getting_started/image-terminology.rst | 8 ++ docs/getting_started/rt-svc-writers-guide.rst | 10 +-- docs/resources/diagrams/arm-cca-software-arch.png | Bin 0 -> 20577 bytes docs/threat_model/threat_model.rst | 7 ++ 6 files changed, 108 insertions(+), 16 deletions(-) create mode 100755 docs/resources/diagrams/arm-cca-software-arch.png diff --git a/docs/components/realm-management-extension.rst b/docs/components/realm-management-extension.rst index 5c580f36d..2c4e0b8a7 100644 --- a/docs/components/realm-management-extension.rst +++ b/docs/components/realm-management-extension.rst @@ -4,8 +4,82 @@ Realm Management Extension (RME) FEAT_RME (or RME for short) is an Armv9-A extension and is one component of the `Arm Confidential Compute Architecture (Arm CCA)`_. TF-A supports RME starting -from version 2.6. This document provides instructions on how to build and run -TF-A with RME. +from version 2.6. This chapter discusses the changes to TF-A to support RME and +provides instructions on how to build and run TF-A with RME. + +RME support in TF-A +--------------------- + +The following diagram shows an Arm CCA software architecture with TF-A as the +EL3 firmware. In the Arm CCA architecture there are two additional security +states and address spaces: ``Root`` and ``Realm``. TF-A firmware runs in the +Root world. In the realm world, a Realm Management Monitor firmware (RMM) +manages the execution of Realm VMs and their interaction with the hypervisor. + +.. image:: ../resources/diagrams/arm-cca-software-arch.png + +RME is the hardware extension to support Arm CCA. To support RME, various +changes have been introduced to TF-A. We discuss those changes below. + +Changes to translation tables library +*************************************** +RME adds Root and Realm Physical address spaces. To support this, two new +memory type macros, ``MT_ROOT`` and ``MT_REALM``, have been added to the +:ref:`Translation (XLAT) Tables Library`. These macros are used to configure +memory regions as Root or Realm respectively. + +.. note:: + + Only version 2 of the translation tables library supports the new memory + types. + +Changes to context management +******************************* +A new CPU context for the Realm world has been added. The existing +:ref:`CPU context management API` can be used to manage Realm context. + +Boot flow changes +******************* +In a typical TF-A boot flow, BL2 runs at Secure-EL1. However when RME is +enabled, TF-A runs in the Root world at EL3. Therefore, the boot flow is +modified to run BL2 at EL3 when RME is enabled. In addition to this, a +Realm-world firmware (RMM) is loaded by BL2 in the Realm physical address +space. + +The boot flow when RME is enabled looks like the following: + +1. BL1 loads and executes BL2 at EL3 +2. BL2 loads images including RMM +3. BL2 transfers control to BL31 +4. BL31 initializes SPM (if SPM is enabled) +5. BL31 initializes RMM +6. BL31 transfers control to Normal-world software + +Granule Protection Tables (GPT) library +***************************************** +Isolation between the four physical address spaces is enforced by a process +called Granule Protection Check (GPC) performed by the MMU downstream any +address translation. GPC makes use of Granule Protection Table (GPT) in the +Root world that describes the physical address space assignment of every +page (granule). A GPT library that provides APIs to initialize GPTs and to +transition granules between different physical address spaces has been added. +More information about the GPT library can be found in the +:ref:`Granule Protection Tables Library` chapter. + +RMM Dispatcher (RMMD) +************************ +RMMD is a new standard runtime service that handles the switch to the Realm +world. It initializes the RMM and handles Realm Management Interface (RMI) +SMC calls from Non-secure and Realm worlds. + +Test Realm Payload (TRP) +************************* +TRP is a small test payload that runs at R-EL2 and implements a subset of +the Realm Management Interface (RMI) commands to primarily test EL3 firmware +and the interface between R-EL2 and EL3. When building TF-A with RME enabled, +if a path to an RMM image is not provided, TF-A builds the TRP by default +and uses it as RMM image. Building and running TF-A with RME ------------------------------------ @@ -25,11 +99,8 @@ TF-A. You can use the following command to clone TF-A. git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git -To run the tests, you need an FVP model. You can download a model that supports -RME from the `Arm Architecture Models website`_. Please select the -*Base RevC AEM FVP* model. After extracting the downloaded file, you should be able to -find the *FVP_Base_RevC-2xAEMvA* binary. The instructions below have been tested -with model version 11.15 revision 18. +To run the tests, you need an FVP model. Please use the :ref:`latest version +` of *FVP_Base_RevC-2xAEMvA* model. .. note:: @@ -64,9 +135,7 @@ This produces a TF-A Tests binary (*tftf.bin*) in the *build/fvp/debug* director all fip This produces *bl1.bin* and *fip.bin* binaries in the *build/fvp/debug* directory. -The above command also builds a Test Realm Payload (TRP), which is a small test -payload that implements Realm Monitor Management (RMM) functionalities and runs -in the realm world (R-EL2). The TRP binary is packaged in *fip.bin*. +The above command also builds TRP. The TRP binary is packaged in *fip.bin*. Four-world execution with Hafnium and TF-A Tests **************************************************** diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index ef500ff05..0831dc056 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -26,6 +26,13 @@ tables. The details of this library can be found in TF-A can be built to support either AArch64 or AArch32 execution state. +.. note:: + + The descriptions in this chapter are for the Arm TrustZone architecture. + For changes to the firmware design for the + `Arm Confidential Compute Architecture (Arm CCA)`_ please refer to the + chapter :ref:`Realm Management Extension (RME)`. + Cold boot --------- @@ -2722,7 +2729,7 @@ kernel at boot time. These can be found in the ``fdts`` directory. -------------- -*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.* .. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf .. _SMCCC: https://developer.arm.com/docs/den0028/latest @@ -2731,5 +2738,6 @@ kernel at boot time. These can be found in the ``fdts`` directory. .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest .. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest .. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a +.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture .. |Image 1| image:: ../resources/diagrams/rt-svc-descs-layout.png diff --git a/docs/getting_started/image-terminology.rst b/docs/getting_started/image-terminology.rst index 5993d6e7a..a90ec0b3f 100644 --- a/docs/getting_started/image-terminology.rst +++ b/docs/getting_started/image-terminology.rst @@ -92,6 +92,14 @@ In systems where 3rd level images are provided by different vendors, the abbreviated name should identify the vendor as well as the image function. For example, ``AP_BL3_ARM_RAS``. +Realm Monitor Management Firmware: ``RMM`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the Realm-EL2 firmware. It is required if +:ref:`Realm Management Extension (RME)` feature is enabled. If a path to RMM +image is not provided, TF-A builds Test Realm Payload (TRP) image by default +and uses it as the RMM image. + SCP Boot ROM: ``SCP_BL1`` (previously ``BL0``) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/getting_started/rt-svc-writers-guide.rst b/docs/getting_started/rt-svc-writers-guide.rst index b3758b824..5a4be4d48 100644 --- a/docs/getting_started/rt-svc-writers-guide.rst +++ b/docs/getting_started/rt-svc-writers-guide.rst @@ -200,13 +200,13 @@ The handler is responsible for: SMC_RET1(handle, SMC_UNK); #. Determining if the requested function is valid for the calling security - state. SMC Calls can be made from both the normal and trusted worlds and + state. SMC Calls can be made from Non-secure, Secure or Realm worlds and the framework will forward all calls to the service handler. The ``flags`` parameter to this function indicates the caller security state - in bit[0], where a value of ``1`` indicates a non-secure caller. The - ``is_caller_secure(flags)`` and ``is_caller_non_secure(flags)`` can be used to - test this condition. + in bits 0 and 5. The ``is_caller_secure(flags)``, ``is_caller_non_secure(flags)`` + and ``is_caller_realm(flags)`` helper functions can be used to determine whether + the caller's security state is Secure, Non-secure or Realm respectively. If invalid, the request should be completed with: @@ -314,7 +314,7 @@ provide this information.... -------------- -*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2014-2021, Arm Limited and Contributors. All rights reserved.* .. _SMCCC: https://developer.arm.com/docs/den0028/latest .. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf diff --git a/docs/resources/diagrams/arm-cca-software-arch.png b/docs/resources/diagrams/arm-cca-software-arch.png new file mode 100755 index 000000000..979e08387 Binary files /dev/null and b/docs/resources/diagrams/arm-cca-software-arch.png differ diff --git a/docs/threat_model/threat_model.rst b/docs/threat_model/threat_model.rst index 9f26487e9..4a31e7988 100644 --- a/docs/threat_model/threat_model.rst +++ b/docs/threat_model/threat_model.rst @@ -6,6 +6,11 @@ Introduction ************************ This document provides a generic threat model for TF-A firmware. +.. note:: + + This threat model doesn't consider Root and Realm worlds introduced by + :ref:`Realm Management Extension (RME)`. + ************************ Target of Evaluation ************************ @@ -22,8 +27,10 @@ assumptions: - All TF-A images are run from either ROM or on-chip trusted SRAM. This means TF-A is not vulnerable to an attacker that can probe or tamper with off-chip memory. + - Trusted boot is enabled. This means an attacker can't boot arbitrary images that are not approved by platform providers. + - There is no Secure-EL2. We don't consider threats that may come with Secure-EL2 software. -- cgit v1.2.3 From 4333f95bedb5f2b53dcb62e0e9c563794ec33c07 Mon Sep 17 00:00:00 2001 From: Manish Pandey Date: Mon, 15 Nov 2021 15:29:08 +0000 Subject: fix(spm_mm): do not compile if SVE/SME is enabled As spm_mm cannot handle SVE/SME usage in NS world so its better to give compilation error when ENABLE_SVE_FOR_NS=1 or ENABLE_SME_FOR_NS=1. Signed-off-by: Manish Pandey Change-Id: I69dbb272ca681bb020501342008eda20d4c0b096 --- docs/components/secure-partition-manager-mm.rst | 6 +++--- docs/getting_started/build-options.rst | 7 ++++--- services/std_svc/spm_mm/spm_mm.mk | 6 ++++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/components/secure-partition-manager-mm.rst b/docs/components/secure-partition-manager-mm.rst index 30312eef7..4cdb96c10 100644 --- a/docs/components/secure-partition-manager-mm.rst +++ b/docs/components/secure-partition-manager-mm.rst @@ -134,8 +134,8 @@ Interface). This will be referred to as the *Standalone MM Secure Partition* in the rest of this document. To enable SPM support in TF-A, the source code must be compiled with the build -flag ``SPM_MM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm -platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the +flag ``SPM_MM=1``, along with ``EL3_EXCEPTION_HANDLING=1`` and ``ENABLE_SVE_FOR_NS=0``. +On Arm platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the location of the binary that contains the BL32 image (``BL32=path/to/image.bin``) must be specified. @@ -148,7 +148,7 @@ image in the FIP: .. code:: shell BL32=path/to/standalone/mm/sp BL33=path/to/bl33.bin \ - make PLAT=fvp SPM_MM=1 EL3_EXCEPTION_HANDLING=1 ARM_BL31_IN_DRAM=1 all fip + make PLAT=fvp SPM_MM=1 EL3_EXCEPTION_HANDLING=1 ENABLE_SVE_FOR_NS=0 ARM_BL31_IN_DRAM=1 all fip Describing Secure Partition resources ------------------------------------- diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index e7ffd9479..7662a1425 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -305,8 +305,8 @@ Common build options ENABLE_SME_FOR_SWD=1 will cause SME, SVE, and FPU/SIMD instructions in secure world to trap to EL3. SME is an optional architectural feature for AArch64 and TF-A support is experimental. At this time, this build option cannot be - used on systems that have SPD=spmd or ENABLE_RME, and attempting to build - with these options will fail. Default is 0. + used on systems that have SPD=spmd/SPM_MM or ENABLE_RME, and attempting to + build with these options will fail. Default is 0. - ``ENABLE_SME_FOR_SWD``: Boolean option to enable the Scalable Matrix Extension for secure world use along with SVE and FPU/SIMD, ENABLE_SME_FOR_NS @@ -329,7 +329,8 @@ Common build options compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to 1. The default is 1 but is automatically disabled when ENABLE_SME_FOR_NS=1 - since SME encompasses SVE. + since SME encompasses SVE. At this time, this build option cannot be used on + systems that have SPM_MM enabled. - ``ENABLE_SVE_FOR_SWD``: Boolean option to enable SVE for the Secure world. SVE is an optional architectural feature for AArch64. Note that this option diff --git a/services/std_svc/spm_mm/spm_mm.mk b/services/std_svc/spm_mm/spm_mm.mk index 656488b8e..a87bdd878 100644 --- a/services/std_svc/spm_mm/spm_mm.mk +++ b/services/std_svc/spm_mm/spm_mm.mk @@ -10,6 +10,12 @@ endif ifneq (${ARCH},aarch64) $(error "Error: SPM_MM is only supported on aarch64.") endif +ifeq (${ENABLE_SVE_FOR_NS},1) + $(error "Error: SPM_MM is not compatible with ENABLE_SVE_FOR_NS") +endif +ifeq (${ENABLE_SME_FOR_NS},1) + $(error "Error: SPM_MM is not compatible with ENABLE_SME_FOR_NS") +endif SPM_SOURCES := $(addprefix services/std_svc/spm_mm/, \ ${ARCH}/spm_mm_helpers.S \ -- cgit v1.2.3 From 322b344e30cb87b9293060d5946b3c17fe3b9133 Mon Sep 17 00:00:00 2001 From: johpow01 Date: Wed, 13 Oct 2021 13:56:51 -0500 Subject: fix(rme): fixes a shift by 64 bits bug in the RME GPT library Under certain configurations of PPS and L0GPTSZ a macro could result in a right shift by 64 bits. This patch removes that possibility by limiting the total size of each shift to the maximum width of the L0 or L1 index field in a physical address. In addition, it adds more detail about how these values are calculated. Signed-off-by: John Powell Change-Id: Ie71c8e6f922a5bb522a6169701bfc36fc99f765a --- lib/gpt_rme/gpt_rme_private.h | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h index 5770bf7d6..4203bba28 100644 --- a/lib/gpt_rme/gpt_rme_private.h +++ b/lib/gpt_rme/gpt_rme_private.h @@ -117,11 +117,13 @@ typedef enum { /******************************************************************************/ /* + * Width of the L0 index field. + * * If S is greater than or equal to T then there is a single L0 region covering * the entire protected space so there is no L0 index, so the width (and the * derivative mask value) are both zero. If we don't specifically handle this * special case we'll get a negative width value which does not make sense and - * could cause a lot of problems. + * would cause problems. */ #define GPT_L0_IDX_WIDTH(_t) (((_t) > GPT_S_VAL) ? \ ((_t) - GPT_S_VAL) : (0U)) @@ -129,9 +131,16 @@ typedef enum { /* Bit shift for the L0 index field in a PA. */ #define GPT_L0_IDX_SHIFT (GPT_S_VAL) -/* Mask for the L0 index field, must be shifted. */ -#define GPT_L0_IDX_MASK(_t) (0xFFFFFFFFFFFFFFFFUL >> \ - (64U - (GPT_L0_IDX_WIDTH(_t)))) +/* + * Mask for the L0 index field, must be shifted. + * + * The value 0x3FFFFF is 22 bits wide which is the maximum possible width of the + * L0 index within a physical address. This is calculated by + * ((t_max - 1) - s_min + 1) where t_max is 52 for 4PB, the largest PPS, and + * s_min is 30 for 1GB, the smallest L0GPTSZ. + */ +#define GPT_L0_IDX_MASK(_t) (0x3FFFFFUL >> (22U - \ + (GPT_L0_IDX_WIDTH(_t)))) /* Total number of L0 regions. */ #define GPT_L0_REGION_COUNT(_t) ((GPT_L0_IDX_MASK(_t)) + 1U) @@ -146,15 +155,28 @@ typedef enum { /* L1 address attribute macros */ /******************************************************************************/ -/* Width of the L1 index field. */ +/* + * Width of the L1 index field. + * + * This field does not have a special case to handle widths less than zero like + * the L0 index field above since all valid combinations of PGS (p) and L0GPTSZ + * (s) will result in a positive width value. + */ #define GPT_L1_IDX_WIDTH(_p) ((GPT_S_VAL - 1U) - ((_p) + 3U)) /* Bit shift for the L1 index field. */ #define GPT_L1_IDX_SHIFT(_p) ((_p) + 4U) -/* Mask for the L1 index field, must be shifted. */ -#define GPT_L1_IDX_MASK(_p) (0xFFFFFFFFFFFFFFFFUL >> \ - (64U - (GPT_L1_IDX_WIDTH(_p)))) +/* + * Mask for the L1 index field, must be shifted. + * + * The value 0x7FFFFF is 23 bits wide and is the maximum possible width of the + * L1 index within a physical address. It is calculated by + * ((s_max - 1) - (p_min + 4) + 1) where s_max is 39 for 512gb, the largest + * L0GPTSZ, and p_min is 12 for 4KB granules, the smallest PGS. + */ +#define GPT_L1_IDX_MASK(_p) (0x7FFFFFUL >> (23U - \ + (GPT_L1_IDX_WIDTH(_p)))) /* Bit shift for the index of the L1 GPI in a PA. */ #define GPT_L1_GPI_IDX_SHIFT(_p) (_p) -- cgit v1.2.3 From 5869ebd0e87f1de987e51994103440fa8c77b26f Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Fri, 22 Oct 2021 14:44:42 +0200 Subject: fix(plat/arm): fix a VERBOSE trace When the console verbosity is at maximum, fconf_populate_arm_sp() prints the UUID and load address of each secure partition. However, the load address has not been retrieved yet at this point, which means all partitions show a zero load address. Move the trace after we have retrieved the SP's load address from the device tree to make it more meaningful. Change-Id: I58ef7df6c9107a433f61113cafd8f0855c468d40 Signed-off-by: Sandrine Bailleux --- plat/arm/common/fconf/arm_fconf_sp.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 552393c9b..95e08730c 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -66,6 +66,15 @@ int fconf_populate_arm_sp(uintptr_t config) } arm_sp.uuids[index] = uuid_helper; + + /* Read Load address */ + err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); + if (err < 0) { + ERROR("FCONF: cannot read SP load address\n"); + return -1; + } + arm_sp.load_addr[index] = val32; + VERBOSE("FCONF: %s UUID" " %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" " load_addr=%lx\n", @@ -82,14 +91,6 @@ int fconf_populate_arm_sp(uintptr_t config) uuid_helper.uuid_struct.node[4], uuid_helper.uuid_struct.node[5], arm_sp.load_addr[index]); - /* Read Load address */ - err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); - if (err < 0) { - ERROR("FCONF: cannot read SP load address\n"); - return -1; - } - arm_sp.load_addr[index] = val32; - /* Read owner field only for dualroot CoT */ #if defined(ARM_COT_dualroot) /* Owner is an optional field, no need to catch error */ -- cgit v1.2.3 From a539c77185a0df2866d323f5d88f594950725e83 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Thu, 2 Sep 2021 15:25:32 +0100 Subject: build(docs): pin Python dependencies Recently some of our dependencies' dependencies have come into conflict and are now causing errors when trying to install the Python requirements. This change introduces `requirements.in` - a list of our own direct dependencies, and pins them to specific versions. The existing `requirements.txt` file is now automatically generated by the `pip-compile` tool - part of the pip-tools package - and ensures that our dependency tree is also pinned. This is a manual process at present, but our dependencies are updated infrequently enough that it's not introducing any major overhead. Change-Id: I3cd0c11a1a4eccaf0d77b538cfdb94474833b811 Signed-off-by: Chris Kay --- docs/requirements.in | 4 +++ docs/requirements.txt | 76 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 docs/requirements.in diff --git a/docs/requirements.in b/docs/requirements.in new file mode 100644 index 000000000..0d7480345 --- /dev/null +++ b/docs/requirements.in @@ -0,0 +1,4 @@ +pip-tools==6.4.0 +sphinx==2.0.0 +sphinx-rtd-theme==0.4.3 +sphinxcontrib-plantuml==0.15 diff --git a/docs/requirements.txt b/docs/requirements.txt index 358ed0e3c..fbb9c79bb 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,73 @@ -sphinx>=2.0.0 -sphinx-rtd-theme>=0.4.3 -sphinxcontrib-plantuml>=0.15 +# +# This file is autogenerated by pip-compile with python 3.8 +# To update, run: +# +# pip-compile +# +alabaster==0.7.12 + # via sphinx +babel==2.9.1 + # via sphinx +certifi==2021.10.8 + # via requests +charset-normalizer==2.0.7 + # via requests +click==8.0.3 + # via pip-tools +docutils==0.18 + # via sphinx +idna==3.3 + # via requests +imagesize==1.3.0 + # via sphinx +jinja2==3.0.3 + # via sphinx +markupsafe==2.0.1 + # via jinja2 +packaging==21.2 + # via sphinx +pep517==0.12.0 + # via pip-tools +pip-tools==6.4.0 + # via -r requirements.in +pygments==2.10.0 + # via sphinx +pyparsing==2.4.7 + # via packaging +pytz==2021.3 + # via babel +requests==2.26.0 + # via sphinx +snowballstemmer==2.1.0 + # via sphinx +sphinx==2.0.0 + # via + # -r requirements.in + # sphinx-rtd-theme + # sphinxcontrib-plantuml +sphinx-rtd-theme==0.4.3 + # via -r requirements.in +sphinxcontrib-applehelp==1.0.2 + # via sphinx +sphinxcontrib-devhelp==1.0.2 + # via sphinx +sphinxcontrib-htmlhelp==2.0.0 + # via sphinx +sphinxcontrib-jsmath==1.0.1 + # via sphinx +sphinxcontrib-plantuml==0.15 + # via -r requirements.in +sphinxcontrib-qthelp==1.0.3 + # via sphinx +sphinxcontrib-serializinghtml==1.1.5 + # via sphinx +tomli==1.2.2 + # via pep517 +urllib3==1.26.7 + # via requests +wheel==0.37.0 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools -- cgit v1.2.3 From a61940ca739eb89be7c1bb2408a9178c2da5cb70 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 16 Nov 2021 10:24:08 +0000 Subject: fix(docs): fix `FF-A` substitution In this change the `FFA` substitution has been renamed to `FF-A`, as well as the term it substitutes to - the `FFA` term does not exist. Change-Id: I0c33d00d82a5498f7088e6a2b088a0006dfe7f65 Signed-off-by: Chris Kay --- docs/global_substitutions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/global_substitutions.txt b/docs/global_substitutions.txt index af1514675..0cf294665 100644 --- a/docs/global_substitutions.txt +++ b/docs/global_substitutions.txt @@ -16,7 +16,7 @@ .. |EHF| replace:: :term:`EHF` .. |FCONF| replace:: :term:`FCONF` .. |FDT| replace:: :term:`FDT` -.. |FFA| replace:: :term:`FFA` +.. |FF-A| replace:: :term:`FF-A` .. |FIP| replace:: :term:`FIP` .. |FVP| replace:: :term:`FVP` .. |FWU| replace:: :term:`FWU` -- cgit v1.2.3 From 2167c02d656d5ab6123727519b7d2b0cb85b85ac Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 9 Nov 2021 16:20:38 +0000 Subject: build(docs): update Python dependencies Updates the Python dependencies used to build the project's Sphinx documentation to their latest versions. Change-Id: I8baee89c85179a667a3850a7b9705ab76f4d702a Signed-off-by: Chris Kay --- docs/requirements.in | 6 +++--- docs/requirements.txt | 34 ++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/requirements.in b/docs/requirements.in index 0d7480345..192310d07 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,4 +1,4 @@ pip-tools==6.4.0 -sphinx==2.0.0 -sphinx-rtd-theme==0.4.3 -sphinxcontrib-plantuml==0.15 +sphinx==4.2.0 +sphinx-rtd-theme==1.0.0 +sphinxcontrib-plantuml==0.22 diff --git a/docs/requirements.txt b/docs/requirements.txt index fbb9c79bb..5971ec82b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,25 +8,27 @@ alabaster==0.7.12 # via sphinx babel==2.9.1 # via sphinx -certifi==2021.10.8 +certifi==2021.5.30 # via requests -charset-normalizer==2.0.7 +charset-normalizer==2.0.4 # via requests -click==8.0.3 +click==8.0.1 # via pip-tools -docutils==0.18 - # via sphinx -idna==3.3 +docutils==0.16 + # via + # sphinx + # sphinx-rtd-theme +idna==3.2 # via requests -imagesize==1.3.0 +imagesize==1.2.0 # via sphinx -jinja2==3.0.3 +jinja2==3.0.1 # via sphinx markupsafe==2.0.1 # via jinja2 -packaging==21.2 +packaging==21.0 # via sphinx -pep517==0.12.0 +pep517==0.11.0 # via pip-tools pip-tools==6.4.0 # via -r requirements.in @@ -34,18 +36,18 @@ pygments==2.10.0 # via sphinx pyparsing==2.4.7 # via packaging -pytz==2021.3 +pytz==2021.1 # via babel requests==2.26.0 # via sphinx snowballstemmer==2.1.0 # via sphinx -sphinx==2.0.0 +sphinx==4.2.0 # via # -r requirements.in # sphinx-rtd-theme # sphinxcontrib-plantuml -sphinx-rtd-theme==0.4.3 +sphinx-rtd-theme==1.0.0 # via -r requirements.in sphinxcontrib-applehelp==1.0.2 # via sphinx @@ -55,15 +57,15 @@ sphinxcontrib-htmlhelp==2.0.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-plantuml==0.15 +sphinxcontrib-plantuml==0.22 # via -r requirements.in sphinxcontrib-qthelp==1.0.3 # via sphinx sphinxcontrib-serializinghtml==1.1.5 # via sphinx -tomli==1.2.2 +tomli==1.2.1 # via pep517 -urllib3==1.26.7 +urllib3==1.26.6 # via requests wheel==0.37.0 # via pip-tools -- cgit v1.2.3 From 35cc497d0adc8684cdc98a93269f651b7d9e737d Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 10:19:37 +0000 Subject: docs(prerequisites): update to Node.js v16 Updates the Node.js version installed by the prerequisite instructions from v14 to v16, which is the latest LTS release. The instructions for installing the Node Version Manager (NVM) have also been updated for v0.39.0 (previously v0.38.0). Change-Id: I85528b3906305914ba6169b4dc5aafcf5b36a339 Signed-off-by: Chris Kay --- docs/getting_started/prerequisites.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst index f45193ae2..ee301282a 100644 --- a/docs/getting_started/prerequisites.rst +++ b/docs/getting_started/prerequisites.rst @@ -75,7 +75,7 @@ These tools are optional: The standard software package used for debugging software on Arm development platforms and |FVP| models. -- Node.js >= 14 +- Node.js >= 16 Highly recommended, and necessary in order to install and use the packaged Git hooks and helper tools. Without these tools you will need to rely on the @@ -98,13 +98,13 @@ The optional packages can be installed using: sudo apt install device-tree-compiler Additionally, to install an up-to-date version of Node.js, you can use the `Node -Version Manager`_ to install a version of your choosing (we recommend 14, but +Version Manager`_ to install a version of your choosing (we recommend 16, but later LTS versions might offer a more stable experience): .. code:: shell - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | "$SHELL" - exec "$SHELL" -ic "nvm install 14; exec $SHELL" + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | "$SHELL" + exec "$SHELL" -ic "nvm install 16; exec $SHELL" .. _Node Version Manager: https://github.com/nvm-sh/nvm#install--update-script -- cgit v1.2.3 From b0ea465344477ad74295b78678474adb54244bf8 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 10:31:21 +0000 Subject: build(npm): update lockfile format to v2 NPM v7, which is included with Node.js v16, uses version 2 of the lockfile format. To avoid its complaints about the old lockfile version, we're updating the lockfile. This change is backwards-compatible with older versions of NPM. Change-Id: I411ec29ea60ef9a616b99ddb52243fac2b305d28 Signed-off-by: Chris Kay --- package-lock.json | 2722 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 2701 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61caf5705..4060e5fc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,2686 @@ { + "name": "tf-a", + "lockfileVersion": 2, "requires": true, - "lockfileVersion": 1, + "packages": { + "": { + "hasInstallScript": true, + "devDependencies": { + "@commitlint/cli": "^11.0.0", + "@commitlint/config-conventional": "^11.0.0", + "commitizen": "^4.2.4", + "cz-conventional-changelog": "^3.3.0", + "husky": "^5.0.4" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.12.13" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@commitlint/cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", + "integrity": "sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "@commitlint/format": "^11.0.0", + "@commitlint/lint": "^11.0.0", + "@commitlint/load": "^11.0.0", + "@commitlint/read": "^11.0.0", + "chalk": "4.1.0", + "core-js": "^3.6.1", + "get-stdin": "8.0.0", + "lodash": "^4.17.19", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^15.1.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-11.0.0.tgz", + "integrity": "sha512-SNDRsb5gLuDd2PL83yCOQX6pE7gevC79UPFx+GLbLfw6jGnnbO9/tlL76MLD8MOViqGbo7ZicjChO9Gn+7tHhA==", + "dev": true, + "dependencies": { + "conventional-changelog-conventionalcommits": "^4.3.1" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/ensure": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-11.0.0.tgz", + "integrity": "sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug==", + "dev": true, + "dependencies": { + "@commitlint/types": "^11.0.0", + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz", + "integrity": "sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ==", + "dev": true, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/format": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-11.0.0.tgz", + "integrity": "sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg==", + "dev": true, + "dependencies": { + "@commitlint/types": "^11.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz", + "integrity": "sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg==", + "dev": true, + "dependencies": { + "@commitlint/types": "^11.0.0", + "semver": "7.3.2" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/lint": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-11.0.0.tgz", + "integrity": "sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ==", + "dev": true, + "dependencies": { + "@commitlint/is-ignored": "^11.0.0", + "@commitlint/parse": "^11.0.0", + "@commitlint/rules": "^11.0.0", + "@commitlint/types": "^11.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/load": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-11.0.0.tgz", + "integrity": "sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg==", + "dev": true, + "dependencies": { + "@commitlint/execute-rule": "^11.0.0", + "@commitlint/resolve-extends": "^11.0.0", + "@commitlint/types": "^11.0.0", + "chalk": "4.1.0", + "cosmiconfig": "^7.0.0", + "lodash": "^4.17.19", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/message": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-11.0.0.tgz", + "integrity": "sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA==", + "dev": true, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-11.0.0.tgz", + "integrity": "sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-parser": "^3.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/read": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-11.0.0.tgz", + "integrity": "sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g==", + "dev": true, + "dependencies": { + "@commitlint/top-level": "^11.0.0", + "fs-extra": "^9.0.0", + "git-raw-commits": "^2.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz", + "integrity": "sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw==", + "dev": true, + "dependencies": { + "import-fresh": "^3.0.0", + "lodash": "^4.17.19", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/rules": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-11.0.0.tgz", + "integrity": "sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA==", + "dev": true, + "dependencies": { + "@commitlint/ensure": "^11.0.0", + "@commitlint/message": "^11.0.0", + "@commitlint/to-lines": "^11.0.0", + "@commitlint/types": "^11.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-11.0.0.tgz", + "integrity": "sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw==", + "dev": true, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/top-level": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-11.0.0.tgz", + "integrity": "sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/types": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-11.0.0.tgz", + "integrity": "sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==", + "dev": true, + "engines": { + "node": ">=v10.22.0" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cachedir": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz", + "integrity": "sha512-VvxA0xhNqIIfg0V9AmJkDg91DaJwryutH5rVEZAhcNi4iJFj9f+QxmAjgK1LT9I8OgToX27fypX6/MeCXVbBjQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commitizen": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.2.4.tgz", + "integrity": "sha512-LlZChbDzg3Ir3O2S7jSo/cgWp5/QwylQVr59K4xayVq8S4/RdKzSyJkghAiZZHfhh5t4pxunUoyeg0ml1q/7aw==", + "dev": true, + "dependencies": { + "cachedir": "2.2.0", + "cz-conventional-changelog": "3.2.0", + "dedent": "0.7.0", + "detect-indent": "6.0.0", + "find-node-modules": "^2.1.2", + "find-root": "1.1.0", + "fs-extra": "8.1.0", + "glob": "7.1.4", + "inquirer": "6.5.2", + "is-utf8": "^0.2.1", + "lodash": "^4.17.20", + "minimist": "1.2.5", + "strip-bom": "4.0.0", + "strip-json-comments": "3.0.1" + }, + "bin": { + "commitizen": "bin/commitizen", + "cz": "bin/git-cz", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/commitizen/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/commitizen/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/commitizen/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/commitizen/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commitizen/node_modules/cz-conventional-changelog": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.2.0.tgz", + "integrity": "sha512-yAYxeGpVi27hqIilG1nh4A9Bnx4J3Ov+eXy4koL3drrR+IO9GaWPsKjik20ht608Asqi8TQPf0mczhEeyAtMzg==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } + }, + "node_modules/commitizen/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/commitizen/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/commitizen/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/commitizen/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/commitizen/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", + "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.0.tgz", + "integrity": "sha512-sj9tj3z5cnHaSJCYObA9nISf7eq/YjscLPoq6nmew4SiOjxqL2KRpK20fjnjVbpNDjJ2HR3MoVcWKXwbVvzS0A==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commit-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", + "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", + "dev": true + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", + "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0", + "trim-off-newlines": "^1.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-js": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", + "integrity": "sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cz-conventional-changelog": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", + "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } + }, + "node_modules/cz-conventional-changelog/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cz-conventional-changelog/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/cz-conventional-changelog/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cz-conventional-changelog/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-node-modules": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.2.tgz", + "integrity": "sha512-x+3P4mbtRPlSiVE1Qco0Z4YLU8WFiFcuWTf3m75OV9Uzcfs2Bg+O9N+r/K0AnmINBW06KpfqKwYJbFlFq4qNug==", + "dev": true, + "dependencies": { + "findup-sync": "^4.0.0", + "merge": "^2.1.0" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", + "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "dependencies": { + "ini": "^1.3.4" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/husky": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz", + "integrity": "sha512-AM8T/auHXRBxlrfPVLKP6jt49GCM2Zz47m8G3FOMsLmTv8Dj/fKVWE0Rh2d4Qrvmy131xEsdQnb3OXRib67PGg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/typicode" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/husky" + } + ], + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "node_modules/longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha1-eB4YMpaqlPbU2RbcM10NF676I/g=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", + "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "resolve": "^1.20.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", + "dev": true, + "dependencies": { + "global-dirs": "^0.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", + "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "dev": true + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.12.13", @@ -310,16 +2990,6 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -634,8 +3304,8 @@ "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", "dev": true, "requires": { - "JSONStream": "^1.0.4", "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", @@ -1317,6 +3987,16 @@ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -1823,6 +4503,15 @@ "readable-stream": "^3.0.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -1834,15 +4523,6 @@ "strip-ansi": "^6.0.0" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", -- cgit v1.2.3 From 67b29a0861890e7702c091d7e857d5b325669137 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 11:09:13 +0000 Subject: build(npm): update commitlint to v14.1.0 Change-Id: Ied1362e9bac4121fd1512e7dbd847b70458f7b98 Signed-off-by: Chris Kay --- package-lock.json | 1549 ++++++++++++++++++++++++++++++++--------------------- package.json | 4 +- 2 files changed, 952 insertions(+), 601 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4060e5fc0..cf7539c29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,8 +6,8 @@ "": { "hasInstallScript": true, "devDependencies": { - "@commitlint/cli": "^11.0.0", - "@commitlint/config-conventional": "^11.0.0", + "@commitlint/cli": "^14.1.0", + "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", "husky": "^5.0.4" @@ -101,174 +101,166 @@ "node": ">=4" } }, - "node_modules/@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "node_modules/@commitlint/cli": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-14.1.0.tgz", + "integrity": "sha512-Orq62jkl9qAGvjFqhehtAqjGY/duJ8hIRPPIHmGR2jIB96D4VTmazS3ZvqJz2Q9kKr61mLAk/171zm0FVzQCYA==", "dev": true, "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@commitlint/cli": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", - "integrity": "sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "@commitlint/format": "^11.0.0", - "@commitlint/lint": "^11.0.0", - "@commitlint/load": "^11.0.0", - "@commitlint/read": "^11.0.0", - "chalk": "4.1.0", - "core-js": "^3.6.1", - "get-stdin": "8.0.0", + "@commitlint/format": "^14.1.0", + "@commitlint/lint": "^14.1.0", + "@commitlint/load": "^14.1.0", + "@commitlint/read": "^14.0.0", + "@commitlint/types": "^14.0.0", "lodash": "^4.17.19", "resolve-from": "5.0.0", "resolve-global": "1.0.0", - "yargs": "^15.1.0" + "yargs": "^17.0.0" }, "bin": { "commitlint": "cli.js" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/config-conventional": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-11.0.0.tgz", - "integrity": "sha512-SNDRsb5gLuDd2PL83yCOQX6pE7gevC79UPFx+GLbLfw6jGnnbO9/tlL76MLD8MOViqGbo7ZicjChO9Gn+7tHhA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-14.1.0.tgz", + "integrity": "sha512-JuhCqkEv8jyqmd54EpXPsQFpYc/8k7sfP1UziRdEvZSJUCLxz+8Pk4cNS0oF1BtjaWO7ITgXPlIZg47PyApGmg==", "dev": true, "dependencies": { "conventional-changelog-conventionalcommits": "^4.3.1" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/ensure": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-11.0.0.tgz", - "integrity": "sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-14.1.0.tgz", + "integrity": "sha512-xrYvFdqVepT3XA1BmSh88eKbvYKtLuQu98QLfgxVmwS99Kj3yW0sT3D7jGvNsynbIx2dhbXofDyubf/DKkpFrQ==", "dev": true, "dependencies": { - "@commitlint/types": "^11.0.0", + "@commitlint/types": "^14.0.0", "lodash": "^4.17.19" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/execute-rule": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz", - "integrity": "sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-14.0.0.tgz", + "integrity": "sha512-Hh/HLpCBDlrD3Rx2x2pDBx6CU+OtVqGXh7mbFpNihAVx6B0zyZqm/vv0cdwdhfGW5OEn1BhCqHf1ZOvL/DwdWA==", "dev": true, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/format": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-11.0.0.tgz", - "integrity": "sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-14.1.0.tgz", + "integrity": "sha512-sF6engqqHjvxGctWRKjFs/HQeNowlpbVmmoP481b2UMQnVQnjjfXJvQsoLpaqFUvgc2sHM4L85F8BmAw+iHG1w==", "dev": true, "dependencies": { - "@commitlint/types": "^11.0.0", + "@commitlint/types": "^14.0.0", "chalk": "^4.0.0" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/is-ignored": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz", - "integrity": "sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-14.0.0.tgz", + "integrity": "sha512-nJltYjXTa+mk+6SPe35nOZCCvt3Gh5mbDz008KQ4OPcn1GX1NG+pEgz1Kx3agDp/pc+JGnsrr5GV00gygIoloA==", "dev": true, "dependencies": { - "@commitlint/types": "^11.0.0", - "semver": "7.3.2" + "@commitlint/types": "^14.0.0", + "semver": "7.3.5" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/lint": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-11.0.0.tgz", - "integrity": "sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-14.1.0.tgz", + "integrity": "sha512-CApGJEOtWU/CcuPD8HkOR1jdUYpjKutGPaeby9nSFzJhwl/UQOjxc4Nd+2g2ygsMi5l3N4j2sWQYEgccpFC3lA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^11.0.0", - "@commitlint/parse": "^11.0.0", - "@commitlint/rules": "^11.0.0", - "@commitlint/types": "^11.0.0" + "@commitlint/is-ignored": "^14.0.0", + "@commitlint/parse": "^14.0.0", + "@commitlint/rules": "^14.1.0", + "@commitlint/types": "^14.0.0" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/load": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-11.0.0.tgz", - "integrity": "sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-14.1.0.tgz", + "integrity": "sha512-p+HbgjhkqLsnxyjOUdEYHztHCp8n2oLVUJTmRPuP5FXLNevh6Gwmxf+NYC2J0sgD084aV2CFi3qu1W4yHWIknA==", "dev": true, "dependencies": { - "@commitlint/execute-rule": "^11.0.0", - "@commitlint/resolve-extends": "^11.0.0", - "@commitlint/types": "^11.0.0", - "chalk": "4.1.0", + "@commitlint/execute-rule": "^14.0.0", + "@commitlint/resolve-extends": "^14.1.0", + "@commitlint/types": "^14.0.0", + "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", + "chalk": "^4.0.0", "cosmiconfig": "^7.0.0", "lodash": "^4.17.19", - "resolve-from": "^5.0.0" + "resolve-from": "^5.0.0", + "typescript": "^4.4.3" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/message": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-11.0.0.tgz", - "integrity": "sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-14.0.0.tgz", + "integrity": "sha512-316Pum+bwDcZamOQw0DXSY17Dq9EjvL1zKdYIZqneu4lnXN6uFfi53Y/sP5crW6zlLdnuTHe1MnuewXPLHfH1Q==", "dev": true, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-11.0.0.tgz", - "integrity": "sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-14.0.0.tgz", + "integrity": "sha512-49qkk0TcwdxJPZUX8MElEzMlRFIL/cg64P4pk8HotFEm2HYdbxxZp6v3cbVw5WOsnRA0frrs+NNoOcIT83ccMQ==", "dev": true, "dependencies": { - "conventional-changelog-angular": "^5.0.0", - "conventional-commits-parser": "^3.0.0" + "@commitlint/types": "^14.0.0", + "conventional-changelog-angular": "^5.0.11", + "conventional-commits-parser": "^3.2.2" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/read": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-11.0.0.tgz", - "integrity": "sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-14.0.0.tgz", + "integrity": "sha512-WXXcSLBqwXTqnEmB0lbU2TrayDJ2G3qI/lxy1ianVmpQol8p9BjodAA6bYxtYYHdQFVXUrIsclzFP/naWG+hlQ==", "dev": true, "dependencies": { - "@commitlint/top-level": "^11.0.0", - "fs-extra": "^9.0.0", + "@commitlint/top-level": "^14.0.0", + "@commitlint/types": "^14.0.0", + "fs-extra": "^10.0.0", "git-raw-commits": "^2.0.0" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/resolve-extends": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz", - "integrity": "sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-14.1.0.tgz", + "integrity": "sha512-ko80k6QB6E6/OvGNWy4u7gzzWyluDT3VDNL2kfZaDywsnrYntUKyT4Do97gQ7orttITzj2GRtk3KWClVz4rUUQ==", "dev": true, "dependencies": { "import-fresh": "^3.0.0", @@ -277,125 +269,92 @@ "resolve-global": "^1.0.0" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/rules": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-11.0.0.tgz", - "integrity": "sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-14.1.0.tgz", + "integrity": "sha512-6jmv414/1JzGzDI/DS+snAMhcL6roQKPdg0WB3kWTWN52EvWXBFm0HIMGt2H/FlRKxozwVXlQN60/1fNIl98xA==", "dev": true, "dependencies": { - "@commitlint/ensure": "^11.0.0", - "@commitlint/message": "^11.0.0", - "@commitlint/to-lines": "^11.0.0", - "@commitlint/types": "^11.0.0" + "@commitlint/ensure": "^14.1.0", + "@commitlint/message": "^14.0.0", + "@commitlint/to-lines": "^14.0.0", + "@commitlint/types": "^14.0.0", + "execa": "^5.0.0" }, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/to-lines": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-11.0.0.tgz", - "integrity": "sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-14.0.0.tgz", + "integrity": "sha512-uIXk54oJDuYyLpI208s3+cGmJ323yvSJ9LB7yUDMWUeJi2LgRxE2EBZL995kLQdnoAsBBXcLq+VDyppg5bV/cg==", "dev": true, "engines": { - "node": ">=v10.22.0" + "node": ">=v12" } }, "node_modules/@commitlint/top-level": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-11.0.0.tgz", - "integrity": "sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-14.0.0.tgz", + "integrity": "sha512-MZDKZfWfl9g4KozgWBGTCrI2cXkMHnBFlhwvEfrAu5G8wd5aL1f2uWEUMnBMjUikmhVj99i1pzge4XFWHQ29wQ==", "dev": true, "dependencies": { "find-up": "^5.0.0" }, "engines": { - "node": ">=v10.22.0" - } - }, - "node_modules/@commitlint/top-level/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=v12" } }, - "node_modules/@commitlint/top-level/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/@commitlint/types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-14.0.0.tgz", + "integrity": "sha512-sIls1nP2uSbGL466edYlh8mn7O/WP4i3bcvP+2DMhkscRCSgaPhNRWDilhYVsHt2Vu1HTQ27uT0Bj5/Lt2+EcQ==", "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "chalk": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=v12" } }, - "node_modules/@commitlint/top-level/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" }, "engines": { - "node": ">=10" + "node": ">=10.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "cosmiconfig": ">=6" } }, - "node_modules/@commitlint/types": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-11.0.0.tgz", - "integrity": "sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==", - "dev": true, - "engines": { - "node": ">=v10.22.0" - } + "node_modules/@endemolshinegroup/cosmiconfig-typescript-loader/node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true }, "node_modules/@types/minimist": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", - "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "node_modules/@types/parse-json": { @@ -414,9 +373,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -437,6 +396,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", @@ -452,15 +417,6 @@ "node": ">=0.10.0" } }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -489,6 +445,12 @@ "node": ">=8" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "node_modules/cachedir": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz", @@ -574,14 +536,14 @@ "dev": true }, "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "node_modules/color-convert": { @@ -763,9 +725,9 @@ "dev": true }, "node_modules/conventional-changelog-angular": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", - "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", "dev": true, "dependencies": { "compare-func": "^2.0.0", @@ -796,9 +758,9 @@ "dev": true }, "node_modules/conventional-commits-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", - "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", + "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==", "dev": true, "dependencies": { "is-text-path": "^1.0.1", @@ -806,8 +768,7 @@ "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", - "through2": "^4.0.0", - "trim-off-newlines": "^1.0.0" + "through2": "^4.0.0" }, "bin": { "conventional-commits-parser": "cli.js" @@ -816,17 +777,6 @@ "node": ">=10" } }, - "node_modules/core-js": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", - "integrity": "sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -843,6 +793,41 @@ "node": ">=10" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/cz-conventional-changelog": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", @@ -989,6 +974,15 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -1016,6 +1010,15 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -1025,6 +1028,53 @@ "node": ">=0.8.0" } }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -1092,16 +1142,19 @@ "dev": true }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/findup-sync": { @@ -1120,18 +1173,17 @@ } }, "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/fs.realpath": { @@ -1155,10 +1207,10 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { "node": ">=10" @@ -1305,6 +1357,15 @@ "node": ">=10" } }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/husky": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz", @@ -1552,9 +1613,9 @@ "dev": true }, "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -1620,6 +1681,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", @@ -1718,15 +1791,18 @@ "dev": true }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -1735,6 +1811,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "node_modules/lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", @@ -1762,10 +1844,16 @@ "node": ">=10" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/map-obj": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", - "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "engines": { "node": ">=8" @@ -1805,6 +1893,12 @@ "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", "dev": true }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "node_modules/micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -1875,13 +1969,13 @@ "dev": true }, "node_modules/normalize-package-data": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", - "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, "dependencies": { "hosted-git-info": "^4.0.1", - "resolve": "^1.20.0", + "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" }, @@ -1889,19 +1983,16 @@ "node": ">=10" } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "path-key": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/once": { @@ -1935,30 +2026,33 @@ } }, "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -2027,6 +2121,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2105,6 +2208,58 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -2177,12 +2332,6 @@ "node": ">=8" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2192,12 +2341,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -2306,10 +2449,13 @@ "dev": true }, "node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -2317,11 +2463,26 @@ "node": ">=10" } }, - "node_modules/set-blocking": { + "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/signal-exit": { "version": "3.0.3", @@ -2329,6 +2490,25 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -2356,9 +2536,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", - "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "node_modules/split2": { @@ -2380,26 +2560,26 @@ } }, "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -2411,7 +2591,16 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" } }, "node_modules/strip-indent": { @@ -2504,13 +2693,30 @@ "node": ">=8" } }, - "node_modules/trim-off-newlines": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "dev": true, + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" } }, "node_modules/tslib": { @@ -2531,6 +2737,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -2568,12 +2787,6 @@ "which": "bin/which" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -2584,9 +2797,9 @@ } }, "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -2594,7 +2807,10 @@ "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrappy": { @@ -2604,10 +2820,13 @@ "dev": true }, "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/yallist": { "version": "4.0.0", @@ -2625,45 +2844,37 @@ } }, "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", + "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, "engines": { "node": ">=6" } @@ -2760,138 +2971,130 @@ } } }, - "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, "@commitlint/cli": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-11.0.0.tgz", - "integrity": "sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-14.1.0.tgz", + "integrity": "sha512-Orq62jkl9qAGvjFqhehtAqjGY/duJ8hIRPPIHmGR2jIB96D4VTmazS3ZvqJz2Q9kKr61mLAk/171zm0FVzQCYA==", "dev": true, "requires": { - "@babel/runtime": "^7.11.2", - "@commitlint/format": "^11.0.0", - "@commitlint/lint": "^11.0.0", - "@commitlint/load": "^11.0.0", - "@commitlint/read": "^11.0.0", - "chalk": "4.1.0", - "core-js": "^3.6.1", - "get-stdin": "8.0.0", + "@commitlint/format": "^14.1.0", + "@commitlint/lint": "^14.1.0", + "@commitlint/load": "^14.1.0", + "@commitlint/read": "^14.0.0", + "@commitlint/types": "^14.0.0", "lodash": "^4.17.19", "resolve-from": "5.0.0", "resolve-global": "1.0.0", - "yargs": "^15.1.0" + "yargs": "^17.0.0" } }, "@commitlint/config-conventional": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-11.0.0.tgz", - "integrity": "sha512-SNDRsb5gLuDd2PL83yCOQX6pE7gevC79UPFx+GLbLfw6jGnnbO9/tlL76MLD8MOViqGbo7ZicjChO9Gn+7tHhA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-14.1.0.tgz", + "integrity": "sha512-JuhCqkEv8jyqmd54EpXPsQFpYc/8k7sfP1UziRdEvZSJUCLxz+8Pk4cNS0oF1BtjaWO7ITgXPlIZg47PyApGmg==", "dev": true, "requires": { "conventional-changelog-conventionalcommits": "^4.3.1" } }, "@commitlint/ensure": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-11.0.0.tgz", - "integrity": "sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-14.1.0.tgz", + "integrity": "sha512-xrYvFdqVepT3XA1BmSh88eKbvYKtLuQu98QLfgxVmwS99Kj3yW0sT3D7jGvNsynbIx2dhbXofDyubf/DKkpFrQ==", "dev": true, "requires": { - "@commitlint/types": "^11.0.0", + "@commitlint/types": "^14.0.0", "lodash": "^4.17.19" } }, "@commitlint/execute-rule": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz", - "integrity": "sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-14.0.0.tgz", + "integrity": "sha512-Hh/HLpCBDlrD3Rx2x2pDBx6CU+OtVqGXh7mbFpNihAVx6B0zyZqm/vv0cdwdhfGW5OEn1BhCqHf1ZOvL/DwdWA==", "dev": true }, "@commitlint/format": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-11.0.0.tgz", - "integrity": "sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-14.1.0.tgz", + "integrity": "sha512-sF6engqqHjvxGctWRKjFs/HQeNowlpbVmmoP481b2UMQnVQnjjfXJvQsoLpaqFUvgc2sHM4L85F8BmAw+iHG1w==", "dev": true, "requires": { - "@commitlint/types": "^11.0.0", + "@commitlint/types": "^14.0.0", "chalk": "^4.0.0" } }, "@commitlint/is-ignored": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz", - "integrity": "sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-14.0.0.tgz", + "integrity": "sha512-nJltYjXTa+mk+6SPe35nOZCCvt3Gh5mbDz008KQ4OPcn1GX1NG+pEgz1Kx3agDp/pc+JGnsrr5GV00gygIoloA==", "dev": true, "requires": { - "@commitlint/types": "^11.0.0", - "semver": "7.3.2" + "@commitlint/types": "^14.0.0", + "semver": "7.3.5" } }, "@commitlint/lint": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-11.0.0.tgz", - "integrity": "sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-14.1.0.tgz", + "integrity": "sha512-CApGJEOtWU/CcuPD8HkOR1jdUYpjKutGPaeby9nSFzJhwl/UQOjxc4Nd+2g2ygsMi5l3N4j2sWQYEgccpFC3lA==", "dev": true, "requires": { - "@commitlint/is-ignored": "^11.0.0", - "@commitlint/parse": "^11.0.0", - "@commitlint/rules": "^11.0.0", - "@commitlint/types": "^11.0.0" + "@commitlint/is-ignored": "^14.0.0", + "@commitlint/parse": "^14.0.0", + "@commitlint/rules": "^14.1.0", + "@commitlint/types": "^14.0.0" } }, "@commitlint/load": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-11.0.0.tgz", - "integrity": "sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-14.1.0.tgz", + "integrity": "sha512-p+HbgjhkqLsnxyjOUdEYHztHCp8n2oLVUJTmRPuP5FXLNevh6Gwmxf+NYC2J0sgD084aV2CFi3qu1W4yHWIknA==", "dev": true, "requires": { - "@commitlint/execute-rule": "^11.0.0", - "@commitlint/resolve-extends": "^11.0.0", - "@commitlint/types": "^11.0.0", - "chalk": "4.1.0", + "@commitlint/execute-rule": "^14.0.0", + "@commitlint/resolve-extends": "^14.1.0", + "@commitlint/types": "^14.0.0", + "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", + "chalk": "^4.0.0", "cosmiconfig": "^7.0.0", "lodash": "^4.17.19", - "resolve-from": "^5.0.0" + "resolve-from": "^5.0.0", + "typescript": "^4.4.3" } }, "@commitlint/message": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-11.0.0.tgz", - "integrity": "sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-14.0.0.tgz", + "integrity": "sha512-316Pum+bwDcZamOQw0DXSY17Dq9EjvL1zKdYIZqneu4lnXN6uFfi53Y/sP5crW6zlLdnuTHe1MnuewXPLHfH1Q==", "dev": true }, "@commitlint/parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-11.0.0.tgz", - "integrity": "sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-14.0.0.tgz", + "integrity": "sha512-49qkk0TcwdxJPZUX8MElEzMlRFIL/cg64P4pk8HotFEm2HYdbxxZp6v3cbVw5WOsnRA0frrs+NNoOcIT83ccMQ==", "dev": true, "requires": { - "conventional-changelog-angular": "^5.0.0", - "conventional-commits-parser": "^3.0.0" + "@commitlint/types": "^14.0.0", + "conventional-changelog-angular": "^5.0.11", + "conventional-commits-parser": "^3.2.2" } }, "@commitlint/read": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-11.0.0.tgz", - "integrity": "sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-14.0.0.tgz", + "integrity": "sha512-WXXcSLBqwXTqnEmB0lbU2TrayDJ2G3qI/lxy1ianVmpQol8p9BjodAA6bYxtYYHdQFVXUrIsclzFP/naWG+hlQ==", "dev": true, "requires": { - "@commitlint/top-level": "^11.0.0", - "fs-extra": "^9.0.0", + "@commitlint/top-level": "^14.0.0", + "@commitlint/types": "^14.0.0", + "fs-extra": "^10.0.0", "git-raw-commits": "^2.0.0" } }, "@commitlint/resolve-extends": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz", - "integrity": "sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-14.1.0.tgz", + "integrity": "sha512-ko80k6QB6E6/OvGNWy4u7gzzWyluDT3VDNL2kfZaDywsnrYntUKyT4Do97gQ7orttITzj2GRtk3KWClVz4rUUQ==", "dev": true, "requires": { "import-fresh": "^3.0.0", @@ -2901,87 +3104,72 @@ } }, "@commitlint/rules": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-11.0.0.tgz", - "integrity": "sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-14.1.0.tgz", + "integrity": "sha512-6jmv414/1JzGzDI/DS+snAMhcL6roQKPdg0WB3kWTWN52EvWXBFm0HIMGt2H/FlRKxozwVXlQN60/1fNIl98xA==", "dev": true, "requires": { - "@commitlint/ensure": "^11.0.0", - "@commitlint/message": "^11.0.0", - "@commitlint/to-lines": "^11.0.0", - "@commitlint/types": "^11.0.0" + "@commitlint/ensure": "^14.1.0", + "@commitlint/message": "^14.0.0", + "@commitlint/to-lines": "^14.0.0", + "@commitlint/types": "^14.0.0", + "execa": "^5.0.0" } }, "@commitlint/to-lines": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-11.0.0.tgz", - "integrity": "sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-14.0.0.tgz", + "integrity": "sha512-uIXk54oJDuYyLpI208s3+cGmJ323yvSJ9LB7yUDMWUeJi2LgRxE2EBZL995kLQdnoAsBBXcLq+VDyppg5bV/cg==", "dev": true }, "@commitlint/top-level": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-11.0.0.tgz", - "integrity": "sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-14.0.0.tgz", + "integrity": "sha512-MZDKZfWfl9g4KozgWBGTCrI2cXkMHnBFlhwvEfrAu5G8wd5aL1f2uWEUMnBMjUikmhVj99i1pzge4XFWHQ29wQ==", "dev": true, "requires": { "find-up": "^5.0.0" + } + }, + "@commitlint/types": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-14.0.0.tgz", + "integrity": "sha512-sIls1nP2uSbGL466edYlh8mn7O/WP4i3bcvP+2DMhkscRCSgaPhNRWDilhYVsHt2Vu1HTQ27uT0Bj5/Lt2+EcQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "dev": true, + "requires": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" }, "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true } } }, - "@commitlint/types": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-11.0.0.tgz", - "integrity": "sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==", - "dev": true - }, "@types/minimist": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", - "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/parse-json": { @@ -2997,9 +3185,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -3011,6 +3199,12 @@ "color-convert": "^2.0.1" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", @@ -3023,12 +3217,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3054,6 +3242,12 @@ "fill-range": "^7.0.1" } }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, "cachedir": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.2.0.tgz", @@ -3115,14 +3309,14 @@ "dev": true }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "color-convert": { @@ -3272,9 +3466,9 @@ "dev": true }, "conventional-changelog-angular": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", - "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", "dev": true, "requires": { "compare-func": "^2.0.0", @@ -3299,9 +3493,9 @@ "dev": true }, "conventional-commits-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", - "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", + "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==", "dev": true, "requires": { "is-text-path": "^1.0.1", @@ -3309,16 +3503,9 @@ "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", - "through2": "^4.0.0", - "trim-off-newlines": "^1.0.0" + "through2": "^4.0.0" } }, - "core-js": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", - "integrity": "sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==", - "dev": true - }, "cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -3332,6 +3519,34 @@ "yaml": "^1.10.0" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "cz-conventional-changelog": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", @@ -3447,6 +3662,12 @@ "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -3471,12 +3692,52 @@ "is-arrayish": "^0.2.1" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + } + } + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -3532,12 +3793,12 @@ "dev": true }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^5.0.0", + "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, @@ -3554,12 +3815,11 @@ } }, "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" @@ -3583,10 +3843,10 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, "git-raw-commits": { @@ -3694,6 +3954,12 @@ "lru-cache": "^6.0.0" } }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, "husky": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz", @@ -3885,9 +4151,9 @@ "dev": true }, "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "requires": { "has": "^1.0.3" @@ -3932,6 +4198,12 @@ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", @@ -4010,12 +4282,12 @@ "dev": true }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -4024,6 +4296,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", @@ -4045,10 +4323,16 @@ "yallist": "^4.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "map-obj": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", - "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, "meow": { @@ -4076,6 +4360,12 @@ "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", "dev": true }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", @@ -4131,26 +4421,24 @@ "dev": true }, "normalize-package-data": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", - "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, "requires": { "hosted-git-info": "^4.0.1", - "resolve": "^1.20.0", + "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + } + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" } }, "once": { @@ -4178,21 +4466,21 @@ "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^3.0.2" } }, "p-try": { @@ -4240,6 +4528,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -4325,6 +4619,43 @@ "type-fest": "^0.8.1" }, "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -4354,24 +4685,12 @@ "strip-indent": "^3.0.0" } }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -4445,15 +4764,27 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, - "set-blocking": { + "shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "signal-exit": { @@ -4462,6 +4793,22 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -4489,9 +4836,9 @@ } }, "spdx-license-ids": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", - "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "split2": { @@ -4513,23 +4860,23 @@ } }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -4538,6 +4885,12 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -4607,11 +4960,19 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, - "trim-off-newlines": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", - "dev": true + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } }, "tslib": { "version": "1.14.1", @@ -4625,6 +4986,12 @@ "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, + "typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4656,12 +5023,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -4669,9 +5030,9 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -4686,9 +5047,9 @@ "dev": true }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -4704,40 +5065,30 @@ "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", + "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "dependencies": { - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true }, "yocto-queue": { diff --git a/package.json b/package.json index ebd5d55b8..548933402 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "postinstall": "husky install" }, "devDependencies": { - "@commitlint/cli": "^11.0.0", - "@commitlint/config-conventional": "^11.0.0", + "@commitlint/cli": "^14.1.0", + "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", "husky": "^5.0.4" -- cgit v1.2.3 From 3ea076e2e0e8a167d423e5706bb1e562e3b6e09a Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 11:10:52 +0000 Subject: build(npm): update Husky to v7.0.4 Change-Id: I708ac9af9311c23b107041b3fc7f1773a83b36c4 Signed-off-by: Chris Kay --- package-lock.json | 29 +++++++++++------------------ package.json | 2 +- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf7539c29..ec0aef5e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", - "husky": "^5.0.4" + "husky": "^7.0.4" } }, "node_modules/@babel/code-frame": { @@ -1367,25 +1367,18 @@ } }, "node_modules/husky": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz", - "integrity": "sha512-AM8T/auHXRBxlrfPVLKP6jt49GCM2Zz47m8G3FOMsLmTv8Dj/fKVWE0Rh2d4Qrvmy131xEsdQnb3OXRib67PGg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/typicode" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/husky" - } - ], "bin": { "husky": "lib/bin.js" }, "engines": { - "node": ">= 10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, "node_modules/iconv-lite": { @@ -3961,9 +3954,9 @@ "dev": true }, "husky": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz", - "integrity": "sha512-AM8T/auHXRBxlrfPVLKP6jt49GCM2Zz47m8G3FOMsLmTv8Dj/fKVWE0Rh2d4Qrvmy131xEsdQnb3OXRib67PGg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", "dev": true }, "iconv-lite": { diff --git a/package.json b/package.json index 548933402..acaca841b 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,6 @@ "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", - "husky": "^5.0.4" + "husky": "^7.0.4" } } -- cgit v1.2.3 From 6558d8e4526bfddfb885bd943850a37f3b52f676 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 12:11:32 +0000 Subject: build(npm): add license field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adds the `license` field to our `package.json` file, which allows some license checking tools to analyze our dependencies for license incompatibilities. The current state of our licensed dependencies is as follows: ``` $ license-checker --summary ├─ MIT: 198 ├─ ISC: 31 ├─ Apache-2.0: 5 ├─ (MIT OR CC0-1.0): 3 ├─ BSD-3-Clause: 2 ├─ BSD-2-Clause: 2 ├─ 0BSD: 2 ├─ (MIT OR Apache-2.0): 1 ├─ CC-BY-3.0: 1 └─ CC0-1.0: 1 ``` Change-Id: I7b9dae1c9f732c7f7491b5d6557dd193b894d70c Signed-off-by: Chris Kay --- package-lock.json | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/package-lock.json b/package-lock.json index ec0aef5e9..b42786d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "hasInstallScript": true, + "license": "BSD-3-Clause", "devDependencies": { "@commitlint/cli": "^14.1.0", "@commitlint/config-conventional": "^14.1.0", diff --git a/package.json b/package.json index acaca841b..8e448d09b 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "license": "BSD-3-Clause", "private": true, "scripts": { "postinstall": "husky install" -- cgit v1.2.3 From 3a43e6dee4a6e243976e781f6c818278fce3df2a Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 13:40:09 +0000 Subject: build(npm): add additional package metadata Introduces the `name` and `version` fields to the NPM package metadata file, which are used by Standard Version. Change-Id: I5266465f746bf29805f36cd94b5e5c20417d7fd0 Signed-off-by: Chris Kay --- package-lock.json | 5 ++++- package.json | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index b42786d85..430e77893 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,12 @@ { - "name": "tf-a", + "name": "trusted-firmware-a", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { + "name": "trusted-firmware-a", + "version": "2.5.0", "hasInstallScript": true, "license": "BSD-3-Clause", "devDependencies": { diff --git a/package.json b/package.json index 8e448d09b..9f9f1745c 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,6 @@ { + "name": "trusted-firmware-a", + "version": "2.5.0", "license": "BSD-3-Clause", "private": true, "scripts": { -- cgit v1.2.3 From dc59d726e79c26b5a3ee2f1cea2e903d5dd1e191 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 2 Nov 2021 13:23:38 +0000 Subject: build(npm): add Standard Version v9.3.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This tool is used to generate changelogs, tag repositories and bump version numbers across the code-base. In preparation for the v2.6.0 release of TF-A, we will be incorporating it into our release workflow, with the hope that it can reduce some of the workload involved going forward. After this change our dependency license situation is as follows: ``` $ license-checker --summary ├─ MIT: 249 ├─ ISC: 43 ├─ Apache-2.0: 6 ├─ BSD-2-Clause: 3 ├─ (MIT OR CC0-1.0): 3 ├─ BSD-3-Clause: 2 ├─ 0BSD: 2 ├─ (MIT OR Apache-2.0): 1 ├─ BSD*: 1 ├─ CC-BY-3.0: 1 └─ CC0-1.0: 1 ``` Change-Id: Ie41443045ecff22f322d155a4bed8ab5d92208cd Signed-off-by: Chris Kay --- package-lock.json | 1793 +++++++++++++++++++++++++++++++++++++++++++++++++++-- package.json | 3 +- 2 files changed, 1729 insertions(+), 67 deletions(-) diff --git a/package-lock.json b/package-lock.json index 430e77893..64e551337 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,8 @@ "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", - "husky": "^7.0.4" + "husky": "^7.0.4", + "standard-version": "^9.3.2" } }, "node_modules/@babel/code-frame": { @@ -349,6 +350,15 @@ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", "dev": true }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -367,6 +377,12 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, "node_modules/ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -728,6 +744,43 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/conventional-changelog": { + "version": "3.1.24", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz", + "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/conventional-changelog-angular": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", @@ -741,10 +794,40 @@ "node": ">=10" } }, + "node_modules/conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, "node_modules/conventional-changelog-conventionalcommits": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.0.tgz", - "integrity": "sha512-sj9tj3z5cnHaSJCYObA9nISf7eq/YjscLPoq6nmew4SiOjxqL2KRpK20fjnjVbpNDjJ2HR3MoVcWKXwbVvzS0A==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz", + "integrity": "sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==", "dev": true, "dependencies": { "compare-func": "^2.0.0", @@ -755,12 +838,294 @@ "node": ">=10" } }, + "node_modules/conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/conventional-changelog-core/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/conventional-changelog-core/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", + "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/conventional-commit-types": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", "dev": true }, + "node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/conventional-commits-parser": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", @@ -781,6 +1146,34 @@ "node": ">=10" } }, + "node_modules/conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -923,6 +1316,15 @@ "node": ">=8" } }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -966,37 +1368,120 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "node_modules/detect-indent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", - "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "node_modules/dotgitignore/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/dotgitignore/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, "engines": { - "node": ">=0.3.1" + "node": ">=6" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/dotgitignore/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/emoji-regex": { @@ -1176,6 +1661,18 @@ "node": ">= 8" } }, + "node_modules/fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "dependencies": { + "null-check": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -1211,6 +1708,82 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/get-pkg-repo/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -1242,6 +1815,53 @@ "node": ">=10" } }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "dependencies": { + "ini": "^1.3.2" + } + }, "node_modules/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -1307,6 +1927,27 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -1717,6 +2358,12 @@ "node": ">=0.10.0" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1729,12 +2376,24 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1787,6 +2446,52 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1814,6 +2519,12 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, "node_modules/lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", @@ -1959,12 +2670,27 @@ "node": ">= 6" } }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -1992,6 +2718,15 @@ "node": ">=8" } }, + "node_modules/null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2154,6 +2889,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -2493,58 +3243,194 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/standard-version": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz", + "integrity": "sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.24", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.6.1", + "conventional-recommended-bump": "6.1.0", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "fs-access": "^1.0.1", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^16.0.0" + }, + "bin": { + "standard-version": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "node_modules/standard-version/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "node_modules/standard-version/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "color-name": "1.1.3" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "node_modules/standard-version/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/standard-version/node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true + "node_modules/standard-version/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "node_modules/standard-version/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "readable-stream": "^3.0.0" + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-version/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" } }, "node_modules/string_decoder": { @@ -2570,6 +3456,12 @@ "node": ">=8" } }, + "node_modules/stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -2734,6 +3626,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, "node_modules/typescript": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", @@ -2747,6 +3645,19 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz", + "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -2793,6 +3704,12 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -2816,6 +3733,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -3157,6 +4083,12 @@ } } }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -3175,6 +4107,12 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", @@ -3462,25 +4400,292 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "conventional-changelog-angular": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", - "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "conventional-changelog": { + "version": "3.1.24", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz", + "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + } + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "conventional-changelog-conventionalcommits": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz", + "integrity": "sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + } + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", "dev": true, "requires": { "compare-func": "^2.0.0", "q": "^1.5.1" } }, - "conventional-changelog-conventionalcommits": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.0.tgz", - "integrity": "sha512-sj9tj3z5cnHaSJCYObA9nISf7eq/YjscLPoq6nmew4SiOjxqL2KRpK20fjnjVbpNDjJ2HR3MoVcWKXwbVvzS0A==", + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", + "integrity": "sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g==", "dev": true, "requires": { - "compare-func": "^2.0.0", + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", - "q": "^1.5.1" + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "conventional-commit-types": { @@ -3489,6 +4694,16 @@ "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", "dev": true }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, "conventional-commits-parser": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", @@ -3503,6 +4718,28 @@ "through2": "^4.0.0" } }, + "conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "cosmiconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", @@ -3617,6 +4854,12 @@ "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -3659,6 +4902,12 @@ "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", "dev": true }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3674,6 +4923,61 @@ "is-obj": "^2.0.0" } }, + "dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3811,6 +5115,15 @@ "resolve-dir": "^1.0.1" } }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, "fs-extra": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", @@ -3840,6 +5153,75 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -3859,6 +5241,43 @@ "through2": "^4.0.0" } }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "^1.3.2" + } + }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", @@ -3912,6 +5331,19 @@ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -4222,6 +5654,12 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4234,12 +5672,24 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -4278,6 +5728,42 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4299,6 +5785,12 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, "lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", @@ -4411,12 +5903,24 @@ "kind-of": "^6.0.3" } }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -4438,6 +5942,12 @@ "path-key": "^3.0.0" } }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4549,6 +6059,18 @@ "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -4838,6 +6360,15 @@ "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, "split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", @@ -4847,6 +6378,105 @@ "readable-stream": "^3.0.0" } }, + "standard-version": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz", + "integrity": "sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.24", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.6.1", + "conventional-recommended-bump": "6.1.0", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "fs-access": "^1.0.1", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^16.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -4867,6 +6497,12 @@ "strip-ansi": "^6.0.1" } }, + "stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4983,12 +6619,25 @@ "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, "typescript": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", "dev": true }, + "uglify-js": { + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz", + "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==", + "dev": true, + "optional": true + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -5026,6 +6675,12 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -5043,6 +6698,12 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 9f9f1745c..0a284a8f6 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", "cz-conventional-changelog": "^3.3.0", - "husky": "^7.0.4" + "husky": "^7.0.4", + "standard-version": "^9.3.2" } } -- cgit v1.2.3 From fa3a13824a8b025cbd69c0efa435892c81734448 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Fri, 12 Nov 2021 15:48:44 +0000 Subject: build(hooks): add commitlint checks for trailers This change adds checks for the `Change-Id` and `Signed-off-by` trailers. These are already required by Gerrit, so they have been configured as warnings as an early heads-up after committing without needing to push. This also renames the commitlint configuration file to align it with the style used by Standard Version when it's eventually introduced: `commitlint.config.js` -> `.commitlintrc.js` Change-Id: I4e3c158e6b3a5407fabd873360d5efce86ebd19e Signed-off-by: Chris Kay --- .commitlintrc.js | 31 +++++++++++++++++++++++++++++++ commitlint.config.js | 14 -------------- 2 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 .commitlintrc.js delete mode 100644 commitlint.config.js diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 000000000..648246c4a --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* eslint-env es6 */ + +"use strict"; + +const cz = require("./.cz.json"); +const { "trailer-exists": trailerExists } = require("@commitlint/rules").default; + +module.exports = { + extends: ["@commitlint/config-conventional"], + plugins: [ + { + rules: { + "signed-off-by-exists": trailerExists, + "change-id-exists": trailerExists, + }, + }, + ], + rules: { + "body-max-line-length": [1, "always", cz.maxLineWidth], /* Warning */ + "header-max-length": [1, "always", cz.maxHeaderWidth], /* Warning */ + + "change-id-exists": [1, "always", "Change-Id:"], /* Warning */ + "signed-off-by-exists": [1, "always", "Signed-off-by:"], /* Warning */ + }, +}; diff --git a/commitlint.config.js b/commitlint.config.js deleted file mode 100644 index 94cad8f2b..000000000 --- a/commitlint.config.js +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-env node */ - -"use strict"; - -const config = require("./.cz.json"); - -module.exports = { - extends: ["@commitlint/config-conventional"], - rules: { - "header-max-length": [1, "always", config.maxHeaderWidth], /* Warning */ - "body-max-line-length": [1, "always", config.maxLineWidth], /* Warning */ - "signed-off-by": [0, "always", "Signed-off-by:"] /* Disabled - buggy */ - } -}; -- cgit v1.2.3 From c76556a01769dd699c437ac4390b11dec38017c6 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 9 Nov 2021 16:14:36 +0000 Subject: build(docs): add support for Markdown documentation This changes adds support for building Markdown documentation into Sphinx with [MyST]. We'll make use of this in a later patch, where we introduce automatically-generated Markdown documentation that needs to be compiled as part of the Sphinx documentation. [MyST]: https://myst-parser.readthedocs.io/en/latest Change-Id: I2a241a588c579fac1a81e1853479908928be1fc8 Signed-off-by: Chris Kay --- docs/conf.py | 4 ++-- docs/requirements.in | 1 + docs/requirements.txt | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 356be99d6..ef77f6bfe 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,13 +20,13 @@ project = 'Trusted Firmware-A' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml'] +extensions = ['myst_parser', 'sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. -source_suffix = '.rst' +source_suffix = ['.md', '.rst'] # The master toctree document. master_doc = 'index' diff --git a/docs/requirements.in b/docs/requirements.in index 192310d07..5d771e58e 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,3 +1,4 @@ +myst-parser==0.15.2 pip-tools==6.4.0 sphinx==4.2.0 sphinx-rtd-theme==1.0.0 diff --git a/docs/requirements.txt b/docs/requirements.txt index 5971ec82b..03b11891c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,6 +6,8 @@ # alabaster==0.7.12 # via sphinx +attrs==21.2.0 + # via markdown-it-py babel==2.9.1 # via sphinx certifi==2021.5.30 @@ -16,6 +18,7 @@ click==8.0.1 # via pip-tools docutils==0.16 # via + # myst-parser # sphinx # sphinx-rtd-theme idna==3.2 @@ -23,9 +26,19 @@ idna==3.2 imagesize==1.2.0 # via sphinx jinja2==3.0.1 - # via sphinx + # via + # myst-parser + # sphinx +markdown-it-py==1.1.0 + # via + # mdit-py-plugins + # myst-parser markupsafe==2.0.1 # via jinja2 +mdit-py-plugins==0.2.8 + # via myst-parser +myst-parser==0.15.2 + # via -r requirements.in packaging==21.0 # via sphinx pep517==0.11.0 @@ -38,6 +51,8 @@ pyparsing==2.4.7 # via packaging pytz==2021.1 # via babel +pyyaml==6.0 + # via myst-parser requests==2.26.0 # via sphinx snowballstemmer==2.1.0 @@ -45,6 +60,7 @@ snowballstemmer==2.1.0 sphinx==4.2.0 # via # -r requirements.in + # myst-parser # sphinx-rtd-theme # sphinxcontrib-plantuml sphinx-rtd-theme==1.0.0 -- cgit v1.2.3 From c4e8edab2174fa9be35f6c9b0cee52ec6397ecc7 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Tue, 9 Nov 2021 20:05:38 +0000 Subject: build(docs): introduce release script This change introduces a new NPM run script to automatically generate the release changelog, as well as bump version numbers across the code-base and create the release tag. This script runs [Standard Version] to execute this, which is a tool designed around automating substantial parts of the release process. This can be done by running: npm run release -- [] Standard Version expects the project to adhere to the [Semantic Versioning] convention which TF-A does not, so you may need to specify the version manually, e.g.: npm run release -- --release-as 2.6.0 Individual steps of the release process may also be skipped at-will, which may be necessary when, for example, tweaking the changelog: npm run release -- --skip.commit --skip.tag Standard Version is configured by the `.versionrc.js` file, which contains information about the Conventional Commits types and scopes used by the project, and how they map to the changelog. To maintain continuity with the existing changelog style - at least to the extent possible in the move from manual to automatic creation - a customized changelog template has been introduced, based on the Conventional Commits template provided by Standard Version. This template package extends the Conventional Commits template package by introducing support for parsing the Conventional Commits scopes into changelog sections, similarly to how they were previously organized. [Standard Version]: https://github.com/conventional-changelog/standard-version [Semantic Versioning]: https://semver.org Change-Id: I5bafa512daedc631baae951651c38c1c62046b0a Signed-off-by: Chris Kay --- .commitlintrc.js | 21 + .cz.json | 71 +- .versionrc.js | 66 + docs/about/maintainers.rst | 6 + docs/change-log.md | 3766 ++++++++++++++++ docs/change-log.rst | 4602 -------------------- package-lock.json | 24 + package.json | 4 +- tools/conventional-changelog-tf-a/index.js | 222 + tools/conventional-changelog-tf-a/package.json | 12 + .../templates/commit-section.hbs | 17 + .../templates/commit.hbs | 15 + .../templates/footer.hbs | 0 .../templates/header.hbs | 13 + .../templates/note-section.hbs | 13 + .../conventional-changelog-tf-a/templates/note.hbs | 3 + .../templates/template.hbs | 9 + 17 files changed, 4259 insertions(+), 4605 deletions(-) create mode 100644 .versionrc.js create mode 100644 docs/change-log.md delete mode 100644 docs/change-log.rst create mode 100644 tools/conventional-changelog-tf-a/index.js create mode 100644 tools/conventional-changelog-tf-a/package.json create mode 100644 tools/conventional-changelog-tf-a/templates/commit-section.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/commit.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/footer.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/header.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/note-section.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/note.hbs create mode 100644 tools/conventional-changelog-tf-a/templates/template.hbs diff --git a/.commitlintrc.js b/.commitlintrc.js index 648246c4a..3bd68bb6c 100644 --- a/.commitlintrc.js +++ b/.commitlintrc.js @@ -11,6 +11,24 @@ const cz = require("./.cz.json"); const { "trailer-exists": trailerExists } = require("@commitlint/rules").default; +/* + * Recursively fetch the project's supported scopes from the Commitizen configuration file. We use + * permit only the blessed scope for each section to encourage developers to use a consistent scope + * scheme. + */ +function getScopes(sections) { + return sections.flatMap(section => { + const scopes = section.scopes; + const subscopes = getScopes(section.sections || []); + + const scope = scopes ? [ scopes[0] ] : []; /* Only use the blessed scope */ + + return scope.concat(subscopes); + }) +}; + +const scopes = getScopes(cz.sections); /* Contains every blessed scope */ + module.exports = { extends: ["@commitlint/config-conventional"], plugins: [ @@ -27,5 +45,8 @@ module.exports = { "change-id-exists": [1, "always", "Change-Id:"], /* Warning */ "signed-off-by-exists": [1, "always", "Signed-off-by:"], /* Warning */ + + "scope-case": [2, "always", "kebab-case"], /* Error */ + "scope-enum": [1, "always", scopes] /* Warning */ }, }; diff --git a/.cz.json b/.cz.json index cb500bac4..97d485033 100644 --- a/.cz.json +++ b/.cz.json @@ -1,5 +1,72 @@ { "path": "./node_modules/cz-conventional-changelog", "maxHeaderWidth": 50, - "maxLineWidth": 72 -} \ No newline at end of file + "maxLineWidth": 72, + "types": [ + { + "type": "feat", + "title": "New Features", + "description": "A new feature" + }, + { + "type": "fix", + "title": "Resolved Issues", + "description": "A bug fix" + }, + { + "type": "build", + "title": "Build System", + "description": "Changes that affect the build system or external dependencies", + "hidden": true + }, + { + "type": "ci", + "title": "Continuous Integration", + "description": "Changes to our CI configuration files and scripts", + "hidden": true + }, + { + "type": "docs", + "title": "Build System", + "description": "Documentation-only changes", + "hidden": true + }, + { + "type": "perf", + "title": "Performance Improvements", + "description": "A code change that improves performance", + "hidden": true + }, + { + "type": "refactor", + "title": "Code Refactoring", + "description": "A code change that neither fixes a bug nor adds a feature", + "hidden": true + }, + { + "type": "revert", + "title": "Reverted Changes", + "description": "Changes that revert a previous change", + "hidden": true + }, + { + "type": "style", + "title": "Style", + "description": "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)", + "hidden": true + }, + { + "type": "test", + "title": "Tests", + "description": "Adding missing tests or correcting existing tests", + "hidden": true + }, + { + "type": "chore", + "title": "Miscellaneous", + "description": "Any other change", + "hidden": true + } + ], + "sections": [] +} diff --git a/.versionrc.js b/.versionrc.js new file mode 100644 index 000000000..1046b281b --- /dev/null +++ b/.versionrc.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* eslint-env es6 */ + +"use strict"; + +const cz = require("./.cz.json"); + +/* + * Convert the Commitizen types array into the format accepted by the Conventional Changelog + * Conventional Commits plugin (which our own plugin extends). + */ +const types = cz.types.map(type => { + if (!type.hidden) { + /* + * Conventional Changelog prevents each section from appearing only if it has no designated + * title, regardless of the value of the `hidden` flag. + */ + type.section = type.title; + } + + delete type.title; + delete type.description; + + return type; +}); + +module.exports = { + "header": "# Change Log & Release Notes\n\nThis document contains a summary of the new features, changes, fixes and known\nissues in each release of Trusted Firmware-A.\n", + "preset": { + "name": "tf-a", + "commitUrlFormat": "https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/{{hash}}", + "compareUrlFormat": "https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/{{previousTag}}..{{currentTag}}", + "userUrlFormat": "https://github.com/{{user}}", + + "types": types, + "sections": cz.sections, + }, + "bumpFiles": [ + { + "filename": "Makefile", + "updater": { + "readVersion": function (contents) { + const major = contents.match(/^VERSION_MAJOR\s*:=\s*(\d+?)$/m)[1]; + const minor = contents.match(/^VERSION_MINOR\s*:=\s*(\d+?)$/m)[1]; + + return `${major}.${minor}.0`; + }, + + "writeVersion": function (contents, version) { + const major = version.split(".")[0]; + const minor = version.split(".")[1]; + + contents = contents.replace(/^(VERSION_MAJOR\s*:=\s*)(\d+?)$/m, `$1${major}`); + contents = contents.replace(/^(VERSION_MINOR\s*:=\s*)(\d+?)$/m, `$1${minor}`); + + return contents; + } + } + } + ] +}; diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 7a48601b7..680683dea 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -747,6 +747,12 @@ Threat Model :|G|: `vwadekar`_ :|F|: docs/threat_model/ +Conventional Changelog Extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +:|M|: Chris Kay +:|G|: `CJKay`_ +:|F|: tools/conventional-changelog-tf-a + .. _AlexeiFedorov: https://github.com/AlexeiFedorov .. _Andre-ARM: https://github.com/Andre-ARM .. _Anson-Huang: https://github.com/Anson-Huang diff --git a/docs/change-log.md b/docs/change-log.md new file mode 100644 index 000000000..0d75dc561 --- /dev/null +++ b/docs/change-log.md @@ -0,0 +1,3766 @@ +# Change Log & Release Notes + +This document contains a summary of the new features, changes, fixes and known +issues in each release of Trusted Firmware-A. + +## 2.5.0 (2021-05-17) + +### New Features + +- Architecture support + + - Added support for speculation barrier(`FEAT_SB`) for non-Armv8.5 platforms + starting from Armv8.0 + - Added support for Activity Monitors Extension version 1.1(`FEAT_AMUv1p1`) + - Added helper functions for Random number generator(`FEAT_RNG`) registers + - Added support for Armv8.6 Multi-threaded PMU extensions (`FEAT_MTPMU`) + - Added support for MTE Asymmetric Fault Handling extensions(`FEAT_MTE3`) + - Added support for Privileged Access Never extensions(`FEAT_PANx`) + +- Bootloader images + + - Added PIE support for AArch32 builds + - Enable Trusted Random Number Generator service for BL32(sp_min) + +- Build System + + - Added build option for Arm Feature Modifiers + +- Drivers + + - Added support for interrupts in TZC-400 driver + - Broadcom + - Added support for I2C, MDIO and USB drivers + - Marvell + - Added support for secure read/write of dfc register-set + - Added support for thermal sensor driver + - Implement a3700_core_getc API in console driver + - Added rx training on 10G port + - Marvell Mochi + - Added support for cn913x in PCIe mode + - Marvell Armada A8K + - Added support for TRNG-IP-76 driver and accessing RNG register + - Mediatek MT8192 + - Added support for following drivers + - MPU configuration for SCP/PCIe + - SPM suspend + - Vcore DVFS + - LPM + - PTP3 + - UART save and restore + - Power-off + - PMIC + - CPU hotplug and MCDI support + - SPMC + - MPU + - Mediatek MT8195 + - Added support for following drivers + - GPIO, NCDI, SPMC drivers + - Power-off + - CPU hotplug, reboot and MCDI + - Delay timer and sys timer + - GIC + - NXP + - Added support for + - non-volatile storage API + - chain of trust and trusted board boot using two modes: MBEDTLS and CSF + - fip-handler necessary for DDR initialization + - SMMU and console drivers + - crypto hardware accelerator driver + - following drivers: SD, EMMC, QSPI, FLEXSPI, GPIO, GIC, CSU, PMU, DDR + - NXP Security Monitor and SFP driver + - interconnect config APIs using ARM CCN-CCI driver + - TZC APIs to configure DDR region + - generic timer driver + - Device configuration driver + - IMX + - Added support for image loading and io-storage driver for TBBR fip booting + - Renesas + - Added support for PFC and EMMC driver + - RZ Family: + - G2N, G2E and G2H SoCs + - Added support for watchdog, QoS, PFC and DRAM initialization + - RZG Family: + - G2M + - Added support for QoS and DRAM initialization + - Xilinx + - Added JTAG DCC support for Versal and ZynqMP SoC family. + +- Libraries + + - C standard library + - Added support to print `%` in `snprintf()` and `printf()` APIs + - Added support for strtoull, strtoll, strtoul, strtol APIs from FreeBSD + project + - CPU support + - Added support for + - Cortex_A78C CPU + - Makalu ELP CPU + - Makalu CPU + - Matterhorn ELP CPU + - Neoverse-N2 CPU + - CPU Errata + - Arm Cortex-A76: Added workaround for erratum 1946160 + - Arm Cortex-A77: Added workaround for erratum 1946167 + - Arm Cortex-A78: Added workaround for erratum 1941498 and 1951500 + - Arm Neoverse-N1: Added workaround for erratum 1946160 + - Flattened device tree(libfdt) + - Added support for wrapper function to read UUIDs in string format from dtb + +- Platforms + + - Added support for MediaTek MT8195 + - Added support for Arm RD-N2 board + - Allwinner + - Added support for H616 SoC + - Arm + - Added support for GPT parser + - Protect GICR frames for fused/unused cores + - Arm Morello + - Added VirtIO network device to Morello FVP fdts + - Arm RD-N2 + - Added support for variant 1 of RD-N2 platform + - Enable AMU support + - Arm RD-V1 + - Enable AMU support + - Arm SGI + - Added support for platform variant build option + - Arm TC0 + - Added Matterhorn ELP CPU support + - Added support for opteed + - Arm Juno + - Added support to use hw_config in BL31 + - Use TRNG entropy source for SMCCC TRNG interface + - Condition Juno entropy source with CRC instructions + - Marvell Mochi + - Added support for detection of secure mode + - Marvell ARMADA + - Added support for new compile option A3720_DB_PM_WAKEUP_SRC + - Added support doing system reset via CM3 secure coprocessor + - Made several makefile enhancements required to build WTMI_MULTI_IMG and + TIMDDRTOOL + - Added support for building DOIMAGETOOL tool + - Added new target mrvl_bootimage + - Mediatek MT8192 + - Added support for rtc power off sequence + - Mediatek MT8195 + - Added support for SiP service + - STM32MP1 + - Added support for + - Seeed ODYSSEY SoM and board + - SDMMC2 and I2C2 pins in pinctrl + - I2C2 peripheral in DTS + - PIE for BL32 + - TZC-400 interrupt managament + - Linux Automation MC-1 board + - Renesas RZG + - Added support for identifying EK874 RZ/G2E board + - Added support for identifying HopeRun HiHope RZ/G2H and RZ/G2H boards + - Rockchip + - Added support for stack protector + - QEMU + - Added support for `max` CPU + - Added Cortex-A72 support to `virt` platform + - Enabled trigger reboot from secure pl061 + - QEMU SBSA + - Added support for sbsa-ref Embedded Controller + - NXP + - Added support for warm reset to retain ddr content + - Added support for image loader necessary for loading fip image + - lx2160a SoC Family + - Added support for + - new platform lx2160a-aqds + - new platform lx2160a-rdb + - new platform lx2162a-aqds + - errata handling + - IMX imx8mm + - Added support for trusted board boot + - TI K3 + - Added support for lite device board + - Enabled Cortex-A72 erratum 1319367 + - Enabled Cortex-A53 erratum 1530924 + - Xilinx ZynqMP + - Added support for PS and system reset on WDT restart + - Added support for error management + - Enable support for log messages necessary for debug + - Added support for PM API SMC call for efuse and register access + +- Processes + + - Introduced process for platform deprecation + - Added documentation for TF-A threat model + - Provided a copy of the MIT license to comply with the license requirements + of the arm-gic.h source file (originating from the Linux kernel project and + re-distributed in TF-A). + +- Services + + - Added support for TRNG firmware interface service + - Arm + - Added SiP service to configure Ethos-N NPU + - SPMC + - Added documentation for SPM(Hafnium) SMMUv3 driver + - SPMD + - Added support for + - FFA_INTERRUPT forwading ABI + - FFA_SECONDARY_EP_REGISTER ABI + - FF-A v1.0 boot time power management, SPMC secondary core boot and early + run-time power management + +- Tools + + - FIPTool + - Added mechanism to allow platform specific image UUID + - git hooks + - Added support for conventional commits through commitlint hook, commitizen + hook and husky configuration files. + - NXP tool + - Added support for a tool that creates pbl file from BL2 + - Renesas RZ/G2 + - Added tool support for creating bootparam and cert_header images + - CertCreate + - Added support for platform-defined certificates, keys, and extensions + using the platform's makefile + - shared tools + - Added EFI_GUID representation to uuid helper data structure + +### Changed + +- Common components + + - Print newline after hex address in aarch64 el3_panic function + - Use proper `#address-cells` and `#size-cells` for reserved-memory in dtbs + +- Drivers + + - Move SCMI driver from ST platform directory and make it common to all + platforms + - Arm GICv3 + - Shift eSPI register offset in GICD_OFFSET_64() + - Use mpidr to probe GICR for current CPU + - Arm TZC-400 + - Adjust filter tag if it set to FILTER_BIT_ALL + - Cadence + - Enhance UART driver APIs to put characters to fifo + - Mediatek MT8192 + - Move timer driver to common folder + - Enhanced sys_cirq driver to add more IC services + - Renesas + - Move ddr and delay driver to common directory + - Renesas rcar + - Treat log as device memory in console driver + - Renesas RZ Family: + - G2N and G2H SoCs + - Select MMC_CH1 for eMMC channel + - Marvell + - Added support for checking if TRNG unit is present + - Marvell A3K + - Set TXDCLK_2X_SEL bit during PCIe initialization + - Set mask parameter for every reg_set call + - Marvell Mochi + - Added missing stream IDs configurations + - MbedTLS + - Migrated to Mbed TLS v2.26.0 + - IMX imx8mp + - Change the bl31 physical load address + - QEMU SBSA + - Enable secure variable storage + - SCMI + - Update power domain protocol version to 2.0 + - STM32 + - Remove dead code from nand FMC driver + +- Libraries + + - C Standard Library + - Use macros to reduce duplicated code between snprintf and printf + - CPU support + - Sanity check pointers before use in AArch32 builds + - Arm Cortex-A78 + - Remove rainier cpu workaround for errata 1542319 + - Arm Makalu ELP + - Added "\_arm" suffix to Makalu ELP CPU lib + +- Miscellaneous + + - Editorconfig + - set max line length to 100 + +- Platforms + + - Allwinner + - Added reserved-memory node to DT + - Express memmap more dynamically + - Move SEPARATE_NOBITS_REGION to platforms + - Limit FDT checks to reduce code size + - Use CPUIDLE hardware when available + - Allow conditional compilation of SCPI and native PSCI ops + - Always use a 3MHz RSB bus clock + - Enable workaround for Cortex-A53 erratum 1530924 + - Fixed non-default PRELOADED_BL33_BASE + - Leave CPU power alone during BL31 setup + - Added several psci hooks enhancements to improve system shutdown/reset + sequence + - Return the PMIC to I2C mode after use + - Separate code to power off self and other CPUs + - Split native and SCPI-based PSCI implementations + - Allwinner H6 + - Added R_PRCM security setup for H6 board + - Added SPC security setup for H6 board + - Use RSB for the PMIC connection on H6 + - Arm + - Store UUID as a string, rather than ints + - Replace FIP base and size macro with a generic name + - Move compile time switch from source to dt file + - Don't provide NT_FW_CONFIG when booting hafnium + - Do not setup 'disabled' regulator + - Increase SP max size + - Remove false dependency of ARM_LINUX_KERNEL_AS_BL33 on RESET_TO_BL31 and + allow it to be enabled independently + - Arm FVP + - Do not map GIC region in BL1 and BL2 + - Arm Juno + - Refactor juno_getentropy() to return 64 bits on each call + - Arm Morello + - Remove "virtio-rng" from Morello FVP + - Enable virtIO P9 device for Morello fvp + - Arm RDV1 + - Allow all PSCI callbacks on RD-V1 + - Rename rddaniel to rdv1 + - Arm RDV1MC + - Rename rddanielxlr to rdv1mc + - Initialize TZC-400 controllers + - Arm TC0 + - Updated GICR base address + - Use scmi_dvfs clock index 1 for cores 4-7 through fdt + - Added reserved-memory node for OP-TEE fdts + - Enabled Theodul DSU in TC platform + - OP-TEE as S-EL1 SP with SPMC at S-EL2 + - Update Matterhorm ELP DVFS clock index + - Arm SGI + - Allow access to TZC controller on all chips + - Define memory regions for multi-chip platforms + - Allow access to nor2 flash and system registers from S-EL0 + - Define default list of memory regions for DMC-620 TZC + - Improve macros defining cper buffer memory region + - Refactor DMC-620 error handling SMC function id + - Refactor SDEI specific macros + - Added platform id value for RDN2 platform + - Refactored header file inclusions and inclusion of memory mapping + - Arm RDN2 + - Allow usage of secure partitions on RDN2 platform + - Update GIC redistributor and TZC base address + - Arm SGM775 + - Deprecate Arm sgm775 FVP platform + - Marvell + - Increase TX FIFO EMPTY timeout from 2ms to 3ms + - Update delay code to be compatible with 1200 MHz CPU + - Marvell ARMADA + - Postpone MSS CPU startup to BL31 stage + - Allow builds without MSS support + - Use MSS SRAM in secure mode + - Added missing FORCE, .PHONY and clean targets + - Cleanup MSS SRAM if used for copy + - Move definition of mrvl_flash target to common marvell_common.mk file + - Show informative build messages and blank lines + - Marvell ARMADA A3K + - Added a new target mrvl_uart which builds UART image + - Added checks that WTP, MV_DDR_PATH and CRYPTOPP_PATH are correctly defined + - Allow use of the system Crypto++ library + - Build \$(WTMI_ENC_IMG) in \$(BUILD_PLAT) directory + - Build intermediate files in \$(BUILD_PLAT) directory + - Build UART image files directly in \$(BUILD_UART) subdirectory + - Correctly set DDR_TOPOLOGY and CLOCKSPRESET for WTMI + - Do not use 'echo -e' in Makefile + - Improve 4GB DRAM usage from 3.375 GB to 3.75 GB + - Remove unused variable WTMI_SYSINIT_IMG from Makefile + - Simplify check if WTP variable is defined + - Split building \$(WTMI_MULTI_IMG) and \$(TIMDDRTOOL) + - Marvell ARMADA A8K + - Allow CP1/CP2 mapping at BLE stage + - Mediatek MT8183 + - Added timer V20 compensation + - Nvidia Tegra + - Rename SMC API + - TI K3 + - Make plat_get_syscnt_freq2 helper check CNT_FID0 register + - Fill non-message data fields in sec_proxy with 0x0 + - Update ti_sci_msg_req_reboot ABI to include domain + - Enable USE_COHERENT_MEM only for the generic board + - Explicitly map SEC_SRAM_BASE to 0x0 + - Use BL31_SIZE instead of computing + - Define the correct number of max table entries and increase SRAM size to + account for additional table + - Raspberry Pi4 + - Switch to gicv2.mk and GICV2_SOURCES + - Renesas + - Move headers and assembly files to common folder + - Renesas rzg + - Added device tree memory node enhancements + - Rockchip + - Switch to using common gicv3.mk + - STM32MP1 + - Set BL sizes regardless of flags + - QEMU + - Include gicv2.mk for compiling GICv2 source files + - Change DEVICE2 definition for MMU + - Added helper to calculate the position shift from MPIDR + - QEMU SBSA + - Include libraries for Cortex-A72 + - Increase SHARED_RAM_SIZE + - Addes support in spm_mm for upto 512 cores + - Added support for topology handling + - QTI + - Mandate SMC implementation + - Xilinx + - Rename the IPI CRC checksum macro + - Use fno-jump-tables flag in CPPFLAGS + - Xilinx versal + - Added the IPI CRC checksum macro support + - Mark IPI calls secure/non-secure + - Enable sgi to communicate with linux using IPI + - Remove Cortex-A53 compilation + - Xilinx ZynqMP + - Configure counter frequency during initialization + - Filter errors related to clock gate permissions + - Implement pinctrl request/release EEMI API + - Reimplement pinctrl get/set config parameter EEMI API calls + - Reimplement pinctrl set/get function EEMI API + - Update error codes to match Linux and PMU Firmware + - Update PM version and support PM version check + - Update return type in query functions + - Added missing ids for 43/46/47dr devices + - Checked for DLL status before doing reset + - Disable ITAPDLYENA bit for zero ITAP delay + - Include GICv2 makefile + - Remove the custom crash implementation + +- Services + + - SPMD + - Lock the g_spmd_pm structure + - Declare third cactus instance as UP SP + - Provide number of vCPUs and VM size for first SP + - Remove `chosen` node from SPMC manifests + - Move OP-TEE SP manifest DTS to FVP platform + - Update OP-TEE SP manifest with device-regions node + - Remove device-memory node from SPMC manifests + - SPM_MM + - Use sp_boot_info to set SP context + - SDEI + - Updata the affinity of shared event + +- Tools + + - FIPtool + - Do not print duplicate verbose lines about building fiptool + - CertCreate + - Updated tool for platform defined certs, keys & extensions + - Create only requested certificates + - Avoid duplicates in extension stack + +### Resolved Issues + +- Several fixes for typos and mis-spellings in documentation + +- Build system + + - Fixed \$\{FIP_NAME} to be rebuilt only when needed in Makefile + - Do not mark file targets as .PHONY target in Makefile + +- Drivers + + - Authorization + - Avoid NV counter upgrade without certificate validation + - Arm GICv3 + - Fixed logical issue for num_eints + - Limit SPI ID to avoid misjudgement in GICD_OFFSET() + - Fixed potential GICD context override with ESPI enabled + - Marvell A3700 + - Fixed configuring polarity invert bits + - Arm TZC-400 + - Correct FAIL_CONTROL Privileged bit + - Fixed logical error in FILTER_BIT definitions + - Renesas rcar + - Fixed several coding style violations reported by checkpatch + +- Libraries + + - Arch helpers + - Fixed assertions in processing dynamic relocations for AArch64 builds + - C standard library + - Fixed MISRA issues in memset() ABI + - RAS + - Fixed bug of binary search in RAS interrupt handler + +- Platforms + + - Arm + - Fixed missing copyrights in arm-gic.h file + - Fixed the order of header files in several dts files + - Fixed error message printing in board makefile + - Fixed bug of overriding the last node in image load helper API + - Fixed stdout-path in fdts files of TC0 and N1SDP platforms + - Turn ON/OFF redistributor in sync with GIC CPU interface ON/OFF for css + platforms + - Arm FVP + - Fixed Generic Timer interrupt types in platform dts files + - Arm Juno + - Fixed parallel build issue for romlib config + - Arm SGI + - Fixed bug in SDEI receive event of RAS handler + - Intel Agilex + - Fixed PLAT_MAX_PWR_LVL value + - Marvell + - Fixed SPD handling in dram port + - Marvell ARMADA + - Fixed TRNG return SMC handling + - Fixed the logic used for LD selector mask + - Fixed MSS firmware loader for A8K family + - ST + - Fixed few violations reported by coverity static checks + - STM32MP1 + - Fixed SELFREF_TO_X32 mask in ddr driver + - Do not keep mmc_device_info in stack + - Correct plat_crash_console_flush() + - QEMU SBSA + - Fixed memory type of secure NOR flash + - QTI + - Fixed NUM_APID and REG_APID_MAP() argument in SPMI driver + - Intel + - Do not keep mmc_device_info in stack + - Hisilicon + - Do not keep mmc_device_info in stack + +- Services + + - EL3 runtime + - Fixed the EL2 context save/restore routine by removing EL2 generic timer + system registers + - Added fix for exception handler in BL31 by synchronizing pending EA using + DSB barrier + - SPMD + - Fixed error codes to use int32_t type + - TSPD + - Added bug fix in tspd interrupt handling when TSP_NS_INTR_ASYNC_PREEMPT is + enabled + - TRNG + - Fixed compilation errors with -O0 compile option + - DebugFS + - Checked channel index before calling clone function + - PSCI + - Fixed limit of 256 CPUs caused by cast to unsigned char + - TSP + - Fixed compilation erros when built with GCC 11.0.0 toolchain + +- Tools + + - FIPtool + - Do not call `make clean` for `all` target + - CertCreate + - Fixed bug to avoid cleaning when building the binary + - Used preallocated parts of the HASH struct to avoid leaking HASH struct + fields + - Free arguments copied with strdup + - Free keys after use + - Free X509_EXTENSION structures on stack to avoid leaking them + - Optimized the code to avoid unnecessary attempts to create non-requested + certificates + +## 2.4.0 (2020-11-17) + +### New Features + +- Architecture support + - Armv8.6-A + - Added support for Armv8.6 Enhanced Counter Virtualization (ECV) + - Added support for Armv8.6 Fine Grained Traps (FGT) + - Added support for Armv8.6 WFE trap delays +- Bootloader images + - Added support for Measured Boot +- Build System + - Added build option `COT_DESC_IN_DTB` to create Chain of Trust at runtime + - Added build option `OPENSSL_DIR` to direct tools to OpenSSL libraries + - Added build option `RAS_TRAP_LOWER_EL_ERR_ACCESS` to enable trapping RAS + register accesses from EL1/EL2 to EL3 + - Extended build option `BRANCH_PROTECTION` to support branch target + identification +- Common components + - Added support for exporting CPU nodes to the device tree + - Added support for single and dual-root Chains of Trust in secure partitions +- Drivers + - Added Broadcom RNG driver + - Added Marvell `mg_conf_cm3` driver + - Added System Control and Management Interface (SCMI) driver + - Added STMicroelectronics ETZPC driver + - Arm GICv3 + - Added support for detecting topology at runtime + - Dual Root + - Added support for platform certificates + - Marvell Cache LLC + - Added support for mapping the entire LLC into SRAM + - Marvell CCU + - Added workaround for erratum 3033912 + - Marvell CP110 COMPHY + - Added support for SATA COMPHY polarity inversion + - Added support for USB COMPHY polarity inversion + - Added workaround for erratum IPCE_COMPHY-1353 + - STM32MP1 Clocks + - Added `RTC` as a gateable clock + - Added support for shifted clock selector bit masks + - Added support for using additional clocks as parents +- Libraries + - C standard library + - Added support for hexadecimal and pointer format specifiers in `snprint()` + - Added assembly alternatives for various library functions + - CPU support + - Arm Cortex-A53 + - Added workaround for erratum 1530924 + - Arm Cortex-A55 + - Added workaround for erratum 1530923 + - Arm Cortex-A57 + - Added workaround for erratum 1319537 + - Arm Cortex-A76 + - Added workaround for erratum 1165522 + - Added workaround for erratum 1791580 + - Added workaround for erratum 1868343 + - Arm Cortex-A72 + - Added workaround for erratum 1319367 + - Arm Cortex-A77 + - Added workaround for erratum 1508412 + - Added workaround for erratum 1800714 + - Added workaround for erratum 1925769 + - Arm Neoverse-N1 + - Added workaround for erratum 1868343 + - EL3 Runtime + - Added support for saving/restoring registers related to nested + virtualization in EL2 context switches if the architecture supports it + - FCONF + - Added support for Measured Boot + - Added support for populating Chain of Trust properties + - Added support for loading the `fw_config` image + - Measured Boot + - Added support for event logging +- Platforms + - Added support for Arm Morello + - Added support for Arm TC0 + - Added support for iEi PUZZLE-M801 + - Added support for Marvell OCTEON TX2 T9130 + - Added support for MediaTek MT8192 + - Added support for NXP i.MX 8M Nano + - Added support for NXP i.MX 8M Plus + - Added support for QTI CHIP SC7180 + - Added support for STM32MP151F + - Added support for STM32MP153F + - Added support for STM32MP157F + - Added support for STM32MP151D + - Added support for STM32MP153D + - Added support for STM32MP157D + - Arm + - Added support for platform-owned SPs + - Added support for resetting to BL31 + - Arm FPGA + - Added support for Klein + - Added support for Matterhorn + - Added support for additional CPU clusters + - Arm FVP + - Added support for performing SDEI platform setup at runtime + - Added support for SMCCC's `SMCCC_ARCH_SOC_ID` command + - Added an `id` field under the NV-counter node in the device tree to + differentiate between trusted and non-trusted NV-counters + - Added support for extracting the clock frequency from the timer node in + the device tree + - Arm Juno + - Added support for SMCCC's `SMCCC_ARCH_SOC_ID` command + - Arm N1SDP + - Added support for cross-chip PCI-e + - Marvell + - Added support for AVS reduction + - Marvell ARMADA + - Added support for twin-die combined memory device + - Marvell ARMADA A8K + - Added support for DDR with 32-bit bus width (both ECC and non-ECC) + - Marvell AP806 + - Added workaround for erratum FE-4265711 + - Marvell AP807 + - Added workaround for erratum 3033912 + - Nvidia Tegra + - Added debug printouts indicating SC7 entry sequence completion + - Added support for SDEI + - Added support for stack protection + - Added support for GICv3 + - Added support for SMCCC's `SMCCC_ARCH_SOC_ID` command + - Nvidia Tegra194 + - Added support for RAS exception handling + - Added support for SPM + - NXP i.MX + - Added support for SDEI + - QEMU SBSA + - Added support for the Secure Partition Manager + - QTI + - Added RNG driver + - Added SPMI PMIC arbitrator driver + - Added support for SMCCC's `SMCCC_ARCH_SOC_ID` command + - STM32MP1 + - Added support for exposing peripheral interfaces to the non-secure world + at runtime + - Added support for SCMI clock and reset services + - Added support for STM32MP15x CPU revision Z + - Added support for SMCCC services in `SP_MIN` +- Services + - Secure Payload Dispatcher + - Added a provision to allow clients to retrieve the service UUID + - SPMC + - Added secondary core endpoint information to the SPMC context structure + - SPMD + - Added support for booting OP-TEE as a guest S-EL1 Secure Partition on top + of Hafnium in S-EL2 + - Added a provision for handling SPMC messages to register secondary core + entry points + - Added support for power management operations +- Tools + - CertCreate + - Added support for secure partitions + - CertTool + - Added support for the `fw_config` image + - FIPTool + - Added support for the `fw_config` image + +### Changed + +- Architecture support +- Bootloader images +- Build System + - The top-level Makefile now supports building FipTool on Windows + - The default value of `KEY_SIZE` has been changed to to 2048 when RSA is in + use + - The previously-deprecated macro `__ASSEMBLY__` has now been removed +- Common components + - Certain functions that flush the console will no longer return error + information +- Drivers + - Arm GIC + - Usage of `drivers/arm/gic/common/gic_common.c` has now been deprecated in + favour of `drivers/arm/gic/vX/gicvX.mk` + - Added support for detecting the presence of a GIC600-AE + - Added support for detecting the presence of a GIC-Clayton + - Marvell MCI + - Now performs link tuning for all MCI interfaces to improve performance + - Marvell MoChi + - PIDI masters are no longer forced into a non-secure access level when + `LLC_SRAM` is enabled + - The SD/MMC controllers are now accessible from guest virtual machines + - Mbed TLS + - Migrated to Mbed TLS v2.24.0 + - STM32 FMC2 NAND + - Adjusted FMC node bindings to include an EBI controller node + - STM32 Reset + - Added an optional timeout argument to assertion functions + - STM32MP1 Clocks + - Enabled several additional system clocks during initialization +- Libraries + - C Standard Library + - Improved `memset` performance by avoiding single-byte writes + - Added optimized assembly variants of `memset` + - CPU support + - Renamed Cortex-Hercules to Cortex-A78 + - Renamed Cortex-Hercules AE to Cortex-A78 AE + - Renamed Neoverse Zeus to Neoverse V1 + - Coreboot + - Updated ‘coreboot_get_memory_type’ API to take an extra argument as a + ’memory size’ that used to return a valid memory type. + - libfdt + - Updated to latest upstream version +- Platforms + - Allwinner + - Disabled non-secure access to PRCM power control registers + - Arm + - `BL32_BASE` is now platform-dependent when `SPD_spmd` is enabled + - Added support for loading the Chain of Trust from the device tree + - The firmware update check is now executed only once + - NV-counter base addresses are now loaded from the device tree when + `COT_DESC_IN_DTB` is enabled + - Now loads and populates `fw_config` and `tb_fw_config` + - FCONF population now occurs after caches have been enabled in order to + reduce boot times + - Arm Corstone-700 + - Platform support has been split into both an FVP and an FPGA variant + - Arm FPGA + - DTB and BL33 load addresses have been given sensible default values + - Now reads generic timer counter frequency, GICD and GICR base addresses, + and UART address from DT + - Now treats the primary PL011 UART as an SBSA Generic UART + - Arm FVP + - Secure interrupt descriptions, UART parameters, clock frequencies and + GICv3 parameters are now queried through FCONF + - UART parameters are now queried through the device tree + - Added an owner field to Cactus secure partitions + - Increased the maximum size of BL2 when the Chain of Trust is loaded from + the device tree + - Reduces the maximum size of BL31 + - The `FVP_USE_SP804_TIMER` and `FVP_VE_USE_SP804_TIMER` build options have + been removed in favour of a common `USE_SP804_TIMER` option + - Added a third Cactus partition to manifests + - Device tree nodes now store UUIDs in big-endian + - Arm Juno + - Increased the maximum size of BL2 when optimizations have not been applied + - Reduced the maximum size of BL31 and BL32 + - Marvell AP807 + - Enabled snoop filters + - Marvell ARMADA A3K + - UART recovery images are now suffixed with `.bin` + - Marvell ARMADA A8K + - Option `BL31_CACHE_DISABLE` is now disabled (`0`) by default + - Nvidia Tegra + - Added VPR resize supported check when processing video memory resize + requests + - Added SMMU verification to prevent potential issues caused by undetected + corruption of the SMMU configuration during boot + - The GIC CPU interface is now properly disabled after CPU off + - The GICv2 sources list and the `BL31_SIZE` definition have been made + platform-specific + - The SPE driver will no longer flush the console when writing individual + characters + - Nvidia Tegra194 + - TZDRAM setup has been moved to platform-specific early boot handlers + - Increased verbosity of debug prints for RAS SErrors + - Support for powering down CPUs during CPU suspend has been removed + - Now verifies firewall settings before using resources + - TI K3 + - The UART number has been made configurable through `K3_USART` + - Rockchip RK3368 + - The maximum number of memory map regions has been increased to 20 + - Socionext Uniphier + - The maximum size of BL33 has been increased to support larger bootloaders + - STM32 + - Removed platform-specific DT functions in favour of using existing generic + alternatives + - STM32MP1 + - Increased verbosity of exception reports in debug builds + - Device trees have been updated to align with the Linux kernel + - Now uses the ETZPC driver to configure secure-aware interfaces for + assignment to the non-secure world + - Finished good variants have been added to the board identifier + enumerations + - Non-secure access to clocks and reset domains now depends on their state + of registration + - NEON is now disabled in `SP_MIN` + - The last page of `SYSRAM` is now used as SCMI shared memory + - Checks to verify platform compatibility have been added to verify that an + image is compatible with the chip ID of the running platform + - QEMU SBSA + - Removed support for Arm's Cortex-A53 +- Services + - Renamed SPCI to FF-A + - SPMD + - No longer forwards requests to the non-secure world when retrieving + partition information + - SPMC manifest size is now retrieved directly from SPMD instead of the + device tree + - The FF-A version handler now returns SPMD's version when the origin of the + call is secure, and SPMC's version when the origin of the call is + non-secure + - SPMC + - Updated the manifest to declare CPU nodes in descending order as per the + SPM (Hafnium) multicore requirement + - Updated the device tree to mark 2GB as device memory for the first + partition excluding trusted DRAM region (which is reserved for SPMC) + - Increased the number of EC contexts to the maximum number of PEs as per + the FF-A specification +- Tools + - FIPTool + - Now returns `0` on `help` and `help ` + - Marvell DoImage + - Updated Mbed TLS support to v2.8 + - SPTool + - Now appends CertTool arguments + +### Resolved Issues + +- Bootloader images + - Fixed compilation errors for dual-root Chains of Trust caused by symbol + collision + - BL31 + - Fixed compilation errors on platforms with fewer than 4 cores caused by + initialization code exceeding the end of the stacks + - Fixed compilation errors when building a position-independent image +- Build System + - Fixed invalid empty version strings + - Fixed compilation errors on Windows caused by a non-portable architecture + revision comparison +- Drivers + - Arm GIC + - Fixed spurious interrupts caused by a missing barrier + - STM32 Flexible Memory Controller 2 (FMC2) NAND driver + - Fixed runtime instability caused by incorrect error detection logic + - STM32MP1 Clock driver + - Fixed incorrectly-formatted log messages + - Fixed runtime instability caused by improper clock gating procedures + - STMicroelectronics Raw NAND driver + - Fixed runtime instability caused by incorrect unit conversion when waiting + for NAND readiness +- Libraries + - AMU + - Fixed timeout errors caused by excess error logging + - EL3 Runtime + - Fixed runtime instability caused by improper register save/restore routine + in EL2 + - FCONF + - Fixed failure to initialize GICv3 caused by overly-strict device tree + requirements + - Measured Boot + - Fixed driver errors caused by a missing default value for the `HASH_ALG` + build option + - SPE + - Fixed feature detection check that prevented CPUs supporting SVE from + detecting support for SPE in the non-secure world + - Translation Tables + - Fixed various MISRA-C 2012 static analysis violations +- Platforms + - Allwinner A64 + - Fixed USB issues on certain battery-powered device caused by improperly + activated USB power rail + - Arm + - Fixed compilation errors caused by increase in BL2 size + - Fixed compilation errors caused by missing Makefile dependencies to + generated files when building the FIP + - Fixed MISRA-C 2012 static analysis violations caused by unused structures + in include directives intended to be feature-gated + - Arm FPGA + - Fixed initialization issues caused by incorrect MPIDR topology mapping + logic + - Arm RD-N1-edge + - Fixed compilation errors caused by mismatched parentheses in Makefile + - Arm SGI + - Fixed crashes due to the flash memory used for cold reboot attack + protection not being mapped + - Intel Agilex + - Fixed initialization issues caused by several compounding bugs + - Marvell + - Fixed compilation warnings caused by multiple Makefile inclusions + - Marvell ARMADA A3K + - Fixed boot issue in debug builds caused by checks on the BL33 load address + that are not appropriate for this platform + - Nvidia Tegra + - Fixed incorrect delay timer reads + - Fixed spurious interrupts in the non-secure world during cold boot caused + by the arbitration bit in the memory controller not being cleared + - Fixed faulty video memory resize sequence + - Nvidia Tegra194 + - Fixed incorrect alignment of TZDRAM base address + - NXP iMX8M + - Fixed CPU hot-plug issues caused by race condition + - STM32MP1 + - Fixed compilation errors in highly-parallel builds caused by incorrect + Makefile dependencies + - STM32MP157C-ED1 + - Fixed initialization issues caused by missing device tree hash node + - Raspberry Pi 3 + - Fixed compilation errors caused by incorrect dependency ordering in + Makefile + - Rockchip + - Fixed initialization issues caused by non-critical errors when parsing FDT + being treated as critical + - Rockchip RK3368 + - Fixed runtime instability caused by incorrect CPUID shift value + - QEMU + - Fixed compilation errors caused by incorrect dependency ordering in + Makefile + - QEMU SBSA + - Fixed initialization issues caused by FDT exceeding reserved memory size + - QTI + - Fixed compilation errors caused by inclusion of a non-existent file +- Services + - FF-A (previously SPCI) + - Fixed SPMD aborts caused by incorrect behaviour when the manifest is + page-aligned +- Tools + - Fixed compilation issues when compiling tools from within their respective + directories + - FIPTool + - Fixed command line parsing issues on Windows when using arguments whose + names also happen to be a subset of another's + - Marvell DoImage + - Fixed PKCS signature verification errors at boot on some platforms caused + by generation of misaligned images + +### Known Issues + +- Platforms + - NVIDIA Tegra + - Signed comparison compiler warnings occurring in libfdt are currently + being worked around by disabling the warning for the platform until the + underlying issue is resolved in libfdt + +## 2.3 (2020-04-20) + +### New Features + +- Arm Architecture + - Add support for Armv8.4-SecEL2 extension through the SPCI defined SPMD/SPMC + components. + - Build option to support EL2 context save and restore in the secure world + (CTX_INCLUDE_EL2_REGS). + - Add support for SMCCC v1.2 (introducing the new SMCCC_ARCH_SOC_ID SMC). Note + that the support is compliant, but the SVE registers save/restore will be + done as part of future S-EL2/SPM development. +- BL-specific + - Enhanced BL2 bootloader flow to load secure partitions based on firmware + configuration data (fconf). + - Changes necessary to support SEPARATE_NOBITS_REGION feature + - TSP and BL2_AT_EL3: Add Position Independent Execution `PIE` support +- Build System + - Add support for documentation build as a target in Makefile + - Add `COT` build option to select the Chain of Trust to use when the Trusted + Boot feature is enabled (default: `tbbr`). + - Added creation and injection of secure partition packages into the FIP. + - Build option to support SPMC component loading and run at S-EL1 or S-EL2 + (SPMD_SPM_AT_SEL2). + - Enable MTE support + - Enable Link Time Optimization in GCC + - Enable -Wredundant-decls warning check + - Makefile: Add support to optionally encrypt BL31 and BL32 + - Add support to pass the nt_fw_config DTB to OP-TEE. + - Introduce per-BL `CPPFLAGS`, `ASFLAGS`, and `LDFLAGS` + - build_macros: Add CREATE_SEQ function to generate sequence of numbers +- CPU Support + - cortex-a57: Enable higher performance non-cacheable load forwarding + - Hercules: Workaround for Errata 1688305 + - Klein: Support added for Klein CPU + - Matterhorn: Support added for Matterhorn CPU +- Drivers + - auth: Add `calc_hash` function for hash calculation. Used for authentication + of images when measured boot is enabled. + - cryptocell: Add authenticated decryption framework, and support for + CryptoCell-713 and CryptoCell-712 RSA 3K + - gic600: Add support for multichip configuration and Clayton + - gicv3: Introduce makefile, Add extended PPI and SPI range, Add support for + probing multiple GIC Redistributor frames + - gicv4: Add GICv4 extension for GIC driver + - io: Add an IO abstraction layer to load encrypted firmwares + - mhu: Derive doorbell base address + - mtd: Add SPI-NOR, SPI-NAND, SPI-MEM, and raw NAND framework + - scmi: Allow use of multiple SCMI channels + - scu: Add a driver for snoop control unit +- Libraries + - coreboot: Add memory range parsing and use generic base address + - compiler_rt: Import popcountdi2.c and popcountsi2.c files, aeabi_ldivmode.S + file and dependencies + - debugFS: Add DebugFS functionality + - el3_runtime: Add support for enabling S-EL2 + - fconf: Add Firmware Configuration Framework (fconf) (experimental). + - libc: Add memrchr function + - locks: bakery: Use is_dcache_enabled() helper and add a DMB to the + 'read_cache_op' macro + - psci: Add support to enable different personality of the same soc. + - xlat_tables_v2: Add support to pass shareability attribute for normal memory + region, use get_current_el_maybe_constant() in is_dcache_enabled(), + read-only xlat tables for BL31 memory, and add enable_mmu() +- New Platforms Support + - arm/arm_fpga: New platform support added for FPGA + - arm/rddaniel: New platform support added for rd-daniel platform + - brcm/stingray: New platform support added for Broadcom stingray platform + - nvidia/tegra194: New platform support for Nvidia Tegra194 platform +- Platforms + - allwinner: Implement PSCI system suspend using SCPI, add a msgbox driver for + use with SCPI, and reserve and map space for the SCP firmware + - allwinner: axp: Add AXP805 support + - allwinner: power: Add DLDO4 power rail + - amlogic: axg: Add a build flag when using ATOS as BL32 and support for the + A113D (AXG) platform + - arm/a5ds: Add ethernet node and L2 cache node in devicetree + - arm/common: Add support for the new `dualroot` chain of trust + - arm/common: Add support for SEPARATE_NOBITS_REGION + - arm/common: Re-enable PIE when RESET_TO_BL31=1 + - arm/common: Allow boards to specify second DRAM Base address and to define + PLAT_ARM_TZC_FILTERS + - arm/corstone700: Add support for mhuv2 and stack protector + - arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power domain + descriptor dynamically by leveraging fconf APIs. + - arm/fvp: Add Cactus/Ivy Secure Partition information and use two instances + of Cactus at S-EL1 + - arm/fvp: Add support to run BL32 in TDRAM and BL31 in secure DRAM + - arm/fvp: Add support for GICv4 extension and BL2 hash calculation in BL1 + - arm/n1sdp: Setup multichip gic routing table, update platform macros for + dual-chip setup, introduce platform information SDS region, add support to + update presence of External LLC, and enable the NEOVERSE_N1_EXTERNAL_LLC + flag + - arm/rdn1edge: Add support for dual-chip configuration and use CREATE_SEQ + helper macro to compare chip count + - arm/sgm: Always use SCMI for SGM platforms + - arm/sgm775: Add support for dynamic config using fconf + - arm/sgi: Add multi-chip mode parameter in HW_CONFIG dts, macros for remote + chip device region, chip_id and multi_chip_mode to platform variant info, + and introduce number of chips macro + - brcm: Add BL2 and BL31 support common across Broadcom platforms + - brcm: Add iproc SPI Nor flash support, spi driver, emmc driver, and support + to retrieve plat_toc_flags + - hisilicon: hikey960: Enable system power off callback + - intel: Enable bridge access, SiP SMC secure register access, and uboot + entrypoint support + - intel: Implement platform specific system reset 2 + - intel: Introduce mailbox response length handling + - imx: console: Use CONSOLE_T_BASE for UART base address and generic console_t + data structure + - imx8mm: Provide uart base as build option and add the support for opteed spd + on imx8mq/imx8mm + - imx8qx: Provide debug uart num as build + - imx8qm: Apply clk/pinmux configuration for DEBUG_CONSOLE and provide debug + uart num as build param + - marvell: a8k: Implement platform specific power off and add support for + loading MG CM3 images + - mediatek: mt8183: Add Vmodem/Vcore DVS init level + - qemu: Support optional encryption of BL31 and BL32 images and + ARM_LINUX_KERNEL_AS_BL33 to pass FDT address + - qemu: Define ARMV7_SUPPORTS_VFP + - qemu: Implement PSCI_CPU_OFF and qemu_system_off via semihosting + - renesas: rcar_gen3: Add new board revision for M3ULCB + - rockchip: Enable workaround for erratum 855873, claim a macro to enable hdcp + feature for DP, enable power domains of rk3399 before reset, add support for + UART3 as serial output, and initialize reset and poweroff GPIOs with known + invalid value + - rpi: Implement PSCI CPU_OFF, use MMIO accessor, autodetect Mini-UART vs. + PL011 configuration, and allow using PL011 UART for RPi3/RPi4 + - rpi3: Include GPIO driver in all BL stages and use same "clock-less" setup + scheme as RPi4 + - rpi3/4: Add support for offlining CPUs + - st: stm32mp1: platform.mk: Support generating multiple images in one build, + migrate to implicit rules, derive map file name from target name, generate + linker script with fixed name, and use PHONY for the appropriate targets + - st: stm32mp1: Add support for SPI-NOR, raw NAND, and SPI-NAND boot device, + QSPI, FMC2 driver + - st: stm32mp1: Use stm32mp_get_ddr_ns_size() function, set XN attribute for + some areas in BL2, dynamically map DDR later and non-cacheable during its + test, add a function to get non-secure DDR size, add DT helper for reg by + name, and add compilation flags for boot devices + - socionext: uniphier: Turn on ENABLE_PIE + - ti: k3: Add PIE support + - xilinx: versal: Add set wakeup source, client wakeup, query data, request + wakeup, PM_INIT_FINALIZE, PM_GET_TRUSTZONE_VERSION, PM IOCTL, support for + suspend related, and Get_ChipID APIs + - xilinx: versal: Implement power down/restart related EEMI, SMC handler for + EEMI, PLL related PM, clock related PM, pin control related PM, reset + related PM, device related PM , APIs + - xilinx: versal: Enable ipi mailbox service + - xilinx: versal: Add get_api_version support and support to send PM API to + PMC using IPI + - xilinx: zynqmp: Add checksum support for IPI data, GET_CALLBACK_DATA + function, support to query max divisor, CLK_SET_RATE_PARENT in gem clock + node, support for custom type flags, LPD WDT clock to the pm_clock + structure, idcodes for new RFSoC silicons ZU48DR and ZU49DR, and id for new + RFSoC device ZU39DR +- Security + - Use Speculation Barrier instruction for v8.5+ cores + - Add support for optional firmware encryption feature (experimental). + - Introduce a new `dualroot` chain of trust. + - aarch64: Prevent speculative execution past ERET + - aarch32: Stop speculative execution past exception returns. +- SPCI + - Introduced the Secure Partition Manager Dispatcher (SPMD) component as a new + standard service. +- Tools + - cert_create: Introduce CoT build option and TBBR CoT makefile, and define + the dualroot CoT + - encrypt_fw: Add firmware authenticated encryption tool + - memory: Add show_memory script that prints a representation of the memory + layout for the latest build + +### Changed + +- Arm Architecture + - PIE: Make call to GDT relocation fixup generalized +- BL-Specific + - Increase maximum size of BL2 image + - BL31: Discard .dynsym .dynstr .hash sections to make ENABLE_PIE work + - BL31: Split into two separate memory regions + - Unify BL linker scripts and reduce code duplication. +- Build System + - Changes to drive cert_create for dualroot CoT + - Enable -Wlogical-op always + - Enable -Wshadow always + - Refactor the warning flags + - PIE: Pass PIE options only to BL31 + - Reduce space lost to object alignment + - Set lld as the default linker for Clang builds + - Remove -Wunused-const-variable and -Wpadded warning + - Remove -Wmissing-declarations warning from WARNING1 level +- Drivers + - authentication: Necessary fix in drivers to upgrade to mbedtls-2.18.0 + - console: Integrate UART base address in generic console_t + - gicv3: Change API for GICR_IPRIORITYR accessors and separate GICD and GICR + accessor functions + - io: Change seek offset to signed long long and panic in case of io setup + failure + - smmu: SMMUv3: Changed retry loop to delay timer + - tbbr: Reduce size of hash and ECDSA key buffers when possible +- Library Code + - libc: Consolidate the size_t, unified, and NULL definitions, and unify + intmax_t and uintmax_t on AArch32/64 + - ROMLIB: Optimize memory layout when ROMLIB is used + - xlat_tables_v2: Use ARRAY_SIZE in REGISTER_XLAT_CONTEXT_FULL_SPEC, merge + REGISTER_XLAT_CONTEXT\_{FULL_SPEC,RO_BASE_TABLE}, and simplify end address + checks in mmap_add_region_check() +- Platforms + - allwinner: Adjust SRAM A2 base to include the ARISC vectors, clean up MMU + setup, reenable USE_COHERENT_MEM, remove unused include path, move the + NOBITS region to SRAM A1, convert AXP803 regulator setup code into a driver, + enable clock before resetting I2C/RSB + - allwinner: h6: power: Switch to using the AXP driver + - allwinner: a64: power: Use fdt_for_each_subnode, remove obsolete register + check, remove duplicate DT check, and make sunxi_turn_off_soc static + - allwinner: Build PMIC bus drivers only in BL31, clean up PMIC-related error + handling, and synchronize PMIC enumerations + - arm/a5ds: Change boot address to point to DDR address + - arm/common: Check for out-of-bound accesses in the platform io policies + - arm/corstone700: Updating the kernel arguments to support initramfs, use + fdts DDR memory and XIP rootfs, and set UART clocks to 32MHz + - arm/fvp: Modify multithreaded dts file of DynamIQ FVPs, slightly bump the + stack size for bl1 and bl2, remove re-definition of topology related build + options, stop reclaiming init code with Clang builds, and map only the + needed DRAM region statically in BL31/SP_MIN + - arm/juno: Maximize space allocated to SCP_BL2 + - arm/sgi: Bump bl1 RW limit, mark remote chip shared ram as non-cacheable, + move GIC related constants to board files, include AFF3 affinity in core + position calculation, move bl31_platform_setup to board file, and move + topology information to board folder + - common: Refactor load_auth_image_internal(). + - hisilicon: Remove uefi-tools in hikey and hikey960 documentation + - intel: Modify non secure access function, BL31 address mapping, mailbox's + get_config_status, and stratix10 BL31 parameter handling + - intel: Remove un-needed checks for qspi driver r/w and s10 unused source + code + - intel: Change all global sip function to static + - intel: Refactor common platform code + - intel: Create SiP service header file + - marvell: armada: scp_bl2: Allow loading up to 8 images + - marvell: comphy-a3700: Support SGMII COMPHY power off and fix USB3 powering + on when on lane 2 + - marvell: Consolidate console register calls + - mediatek: mt8183: Protect 4GB~8GB dram memory, refine GIC driver for low + power scenarios, and switch PLL/CLKSQ/ck_off/axi_26m control to SPM + - qemu: Update flash address map to keep FIP in secure FLASH0 + - renesas: rcar_gen3: Update IPL and Secure Monitor Rev.2.0.6, update DDR + setting for H3, M3, M3N, change fixed destination address of BL31 and BL32, + add missing #{address,size}-cells into generated DT, pass DT to OpTee OS, + and move DDR drivers out of staging + - rockchip: Make miniloader ddr_parameter handling optional, cleanup securing + of ddr regions, move secure init to separate file, use base+size for secure + ddr regions, bring TZRAM_SIZE values in lined, and prevent macro expansion + in paths + - rpi: Move plat_helpers.S to common + - rpi3: gpio: Simplify GPIO setup + - rpi4: Skip UART initialisation + - st: stm32m1: Use generic console_t data structure, remove second QSPI flash + instance, update for FMC2 pin muxing, and reduce MAX_XLAT_TABLES to 4 + - socionext: uniphier: Make on-chip SRAM and I/O register regions configurable + - socionext: uniphier: Make PSCI related, counter control, UART, pinmon, NAND + controller, and eMMC controller base addresses configurable + - socionext: uniphier: Change block_addressing flag and the return value type + of .is_usb_boot() to bool + - socionext: uniphier: Run BL33 at EL2, call uniphier_scp_is_running() only + when on-chip STM is supported, define PLAT_XLAT_TABLES_DYNAMIC only for BL2, + support read-only xlat tables, use enable_mmu() in common function, shrink + UNIPHIER_ROM_REGION_SIZE, prepare uniphier_soc_info() for next SoC, extend + boot device detection for future SoCs, make all BL images completely + position-independent, make uniphier_mmap_setup() work with PIE, pass SCP + base address as a function parameter, set buffer offset and length for + io_block dynamically, and use more mmap_add_dynamic_region() for loading + images + - spd/trusty: Disable error messages seen during boot, allow gic base to be + specified with GICD_BASE, and allow getting trusty memsize from + BL32_MEM_SIZE instead of TSP_SEC_MEM_SIZE + - ti: k3: common: Enable ARM cluster power down and rename device IDs to be + more consistent + - ti: k3: drivers: ti_sci: Put sequence number in coherent memory and remove + indirect structure of const data + - xilinx: Move ipi mailbox svc to xilinx common + - xilinx: zynqmp: Use GIC framework for warm restart + - xilinx: zynqmp: pm: Move custom clock flags to typeflags, remove + CLK_TOPSW_LSBUS from invalid clock list and rename FPD WDT clock ID + - xilinx: versal: Increase OCM memory size for DEBUG builds and adjust cpu + clock, Move versal_def.h and versal_private to include directory +- Tools + - sptool: Updated sptool to accommodate building secure partition packages. + +### Resolved Issues + +- Arm Architecture + - Fix crash dump for lower EL +- BL-Specific + - Bug fix: Protect TSP prints with lock + - Fix boot failures on some builds linked with ld.lld. +- Build System + - Fix clang build if CC is not in the path. + - Fix 'BL stage' comment for build macros +- Code Quality + - coverity: Fix various MISRA violations including null pointer violations, C + issues in BL1/BL2/BL31 and FDT helper functions, using boolean essential, + type, and removing unnecessary header file and comparisons to LONG_MAX in + debugfs devfip + - Based on coding guidelines, replace all `unsigned long` depending on if + fixed based on AArch32 or AArch64. + - Unify type of "cpu_idx" and Platform specific defines across PSCI module. +- Drivers + - auth: Necessary fix in drivers to upgrade to mbedtls-2.18.0 + - delay_timer: Fix non-standard frequency issue in udelay + - gicv3: Fix compiler dependent behavior + - gic600: Fix include ordering according to the coding style and power up + sequence +- Library Code + - el3_runtime: Fix stack pointer maintenance on EA handling path, fixup + 'cm_setup_context' prototype, and adds TPIDR_EL2 register to the context + save restore routines + - libc: Fix SIZE_MAX on AArch32 + - locks: T589: Fix insufficient ordering guarantees in bakery lock + - pmf: Fix 'tautological-constant-compare' error, Make the runtime + instrumentation work on AArch32, and Simplify PMF helper macro definitions + across header files + - xlat_tables_v2: Fix assembler warning of PLAT_RO_XLAT_TABLES +- Platforms + - allwinner: Fix H6 GPIO and CCU memory map addresses and incorrect ARISC code + patch offset check + - arm/a5ds: Correct system freq and Cache Writeback Granule, and cleanup + enable-method in devicetree + - arm/fvp: Fix incorrect GIC mapping, BL31 load address and image size for + RESET_TO_BL31=1, topology description of cpus for DynamIQ based FVP, and + multithreaded FVP power domain tree + - arm/fvp: spm-mm: Correcting instructions to build SPM for FVP + - arm/common: Fix ROTPK hash generation for ECDSA encryption, BL2 bug in + dynamic configuration initialisation, and current RECLAIM_INIT_CODE behavior + - arm/rde1edge: Fix incorrect topology tree description + - arm/sgi: Fix the incorrect check for SCMI channel ID + - common: Flush dcache when storing timestamp + - intel: Fix UEFI decompression issue, memory calibration, SMC SIP service, + mailbox config return status, mailbox driver logic, FPGA manager on + reconfiguration, and mailbox send_cmd issue + - imx: Fix shift-overflow errors, the rdc memory region slot's offset, + multiple definition of ipc_handle, missing inclusion of cdefs.h, and correct + the SGIs that used for secure interrupt + - mediatek: mt8183: Fix AARCH64 init fail on CPU0 + - rockchip: Fix definition of struct param_ddr_usage + - rpi4: Fix documentation of armstub config entry + - st: Correct io possible NULL pointer dereference and device_size type, nand + xor_ecc.val assigned value, static analysis tool issues, and fix incorrect + return value and correctly check pwr-regulators node + - xilinx: zynqmp: Correct syscnt freq for QEMU and fix clock models and IDs of + GEM-related clocks + +### Known Issues + +- Build System + - dtb: DTB creation not supported when building on a Windows host. + + This step in the build process is skipped when running on a Windows host. A + known issue from the 1.6 release. + + - Intermittent assertion firing `ASSERT: services/spd/tspd/tspd_main.c:105` +- Coverity + - Intermittent Race condition in Coverity Jenkins Build Job +- Platforms + - arm/juno: System suspend from Linux does not function as documented in the + user guide + + Following the instructions provided in the user guide document does not + result in the platform entering system suspend state as expected. A message + relating to the hdlcd driver failing to suspend will be emitted on the Linux + terminal. + + - mediatek/mt6795: This platform does not build in this release + +## 2.2 (2019-10-22) + +### New Features + +- Architecture + - Enable Pointer Authentication (PAuth) support for Secure World + + - Adds support for ARMv8.3-PAuth in BL1 SMC calls and BL2U image for + firmware updates. + + - Enable Memory Tagging Extension (MTE) support in both secure and non-secure + worlds + + - Adds support for the new Memory Tagging Extension arriving in ARMv8.5. MTE + support is now enabled by default on systems that support it at EL0. + - To enable it at ELx for both the non-secure and the secure world, the + compiler flag `CTX_INCLUDE_MTE_REGS` includes register saving and + restoring when necessary in order to prevent information leakage between + the worlds. + + - Add support for Branch Target Identification (BTI) +- Build System + - Modify FVP makefile for CPUs that support both AArch64/32 + - AArch32: Allow compiling with soft-float toolchain + - Makefile: Add default warning flags + - Add Makefile check for PAuth and AArch64 + - Add compile-time errors for HW_ASSISTED_COHERENCY flag + - Apply compile-time check for AArch64-only CPUs + - build_macros: Add mechanism to prevent bin generation. + - Add support for default stack-protector flag + - spd: opteed: Enable NS_TIMER_SWITCH + - plat/arm: Skip BL2U if RESET_TO_SP_MIN flag is set + - Add new build option to let each platform select which implementation of + spinlocks it wants to use +- CPU Support + - DSU: Workaround for erratum 798953 and 936184 + - Neoverse N1: Force cacheable atomic to near atomic + - Neoverse N1: Workaround for erratum 1073348, 1130799, 1165347, 1207823, + 1220197, 1257314, 1262606, 1262888, 1275112, 1315703, 1542419 + - Neoverse Zeus: Apply the MSR SSBS instruction + - cortex-Hercules/HerculesAE: Support added for Cortex-Hercules and + Cortex-HerculesAE CPUs + - cortex-Hercules/HerculesAE: Enable AMU for Cortex-Hercules and + Cortex-HerculesAE + - cortex-a76AE: Support added for Cortex-A76AE CPU + - cortex-a76: Workaround for erratum 1257314, 1262606, 1262888, 1275112, + 1286807 + - cortex-a65/a65AE: Support added for Cortex-A65 and Cortex-A65AE CPUs + - cortex-a65: Enable AMU for Cortex-A65 + - cortex-a55: Workaround for erratum 1221012 + - cortex-a35: Workaround for erratum 855472 + - cortex-a9: Workaround for erratum 794073 +- Drivers + - console: Allow the console to register multiple times + + - delay: Timeout detection support + + - gicv3: Enabled multi-socket GIC redistributor frame discovery and migrated + ARM platforms to the new API + + - Adds `gicv3_rdistif_probe` function that delegates the responsibility of + discovering the corresponding redistributor base frame to each CPU itself. + + - sbsa: Add SBSA watchdog driver + + - st/stm32_hash: Add HASH driver + + - ti/uart: Add an AArch32 variant +- Library at ROM (romlib) + - Introduce BTI support in Library at ROM (romlib) +- New Platforms Support + - amlogic: g12a: New platform support added for the S905X2 (G12A) platform + - amlogic: meson/gxl: New platform support added for Amlogic Meson S905x (GXL) + - arm/a5ds: New platform support added for A5 DesignStart + - arm/corstone: New platform support added for Corstone-700 + - intel: New platform support added for Agilex + - mediatek: New platform support added for MediaTek mt8183 + - qemu/qemu_sbsa: New platform support added for QEMU SBSA platform + - renesas/rcar_gen3: plat: New platform support added for D3 + - rockchip: New platform support added for px30 + - rockchip: New platform support added for rk3288 + - rpi: New platform support added for Raspberry Pi 4 +- Platforms + - arm/common: Introduce wrapper functions to setup secure watchdog + - arm/fvp: Add Delay Timer driver to BL1 and BL31 and option for defining + platform DRAM2 base + - arm/fvp: Add Linux DTS files for 32 bit threaded FVPs + - arm/n1sdp: Add code for DDR ECC enablement and BL33 copy to DDR, Initialise + CNTFRQ in Non Secure CNTBaseN + - arm/juno: Use shared mbedtls heap between BL1 and BL2 and add basic support + for dynamic config + - imx: Basic support for PicoPi iMX7D, rdc module init, caam module init, + aipstz init, IMX_SIP_GET_SOC_INFO, IMX_SIP_BUILDINFO added + - intel: Add ncore ccu driver + - mediatek/mt81\*: Use new bl31_params_parse() helper + - nvidia: tegra: Add support for multi console interface + - qemu/qemu_sbsa: Adding memory mapping for both FLASH0/FLASH1 + - qemu: Added gicv3 support, new console interface in AArch32, and + sub-platforms + - renesas/rcar_gen3: plat: Add R-Car V3M support, new board revision for + H3ULCB, DBSC4 setting before self-refresh mode + - socionext/uniphier: Support console based on multi-console + - st: stm32mp1: Add OP-TEE, Avenger96, watchdog, LpDDR3, authentication + support and general SYSCFG management + - ti/k3: common: Add support for J721E, Use coherent memory for shared data, + Trap all asynchronous bus errors to EL3 + - xilinx/zynqmp: Add support for multi console interface, Initialize IPI table + from zynqmp_config_setup() +- PSCI + - Adding new optional PSCI hook `pwr_domain_on_finish_late` + - This PSCI hook `pwr_domain_on_finish_late` is similar to + `pwr_domain_on_finish` but is guaranteed to be invoked when the respective + core and cluster are participating in coherency. +- Security + - Speculative Store Bypass Safe (SSBS): Further enhance protection against + Spectre variant 4 by disabling speculative loads/stores (SPSR.SSBS bit) by + default. + - UBSAN support and handlers + - Adds support for the Undefined Behaviour sanitizer. There are two types of + support offered - minimalistic trapping support which essentially + immediately crashes on undefined behaviour and full support with full + debug messages. +- Tools + - cert_create: Add support for bigger RSA key sizes (3KB and 4KB), previously + the maximum size was 2KB. + - fiptool: Add support to build fiptool on Windows. + +### Changed + +- Architecture + - Refactor ARMv8.3 Pointer Authentication support code + - backtrace: Strip PAC field when PAUTH is enabled + - Prettify crash reporting output on AArch64. + - Rework smc_unknown return code path in smc_handler + - Leverage the existing `el3_exit()` return routine for smc_unknown return + path rather than a custom set of instructions. +- BL-Specific + - Invalidate dcache build option for BL2 entry at EL3 + - Add missing support for BL2_AT_EL3 in XIP memory +- Boot Flow + - Add helper to parse BL31 parameters (both versions) + - Factor out cross-BL API into export headers suitable for 3rd party code + - Introduce lightweight BL platform parameter library +- Drivers + - auth: Memory optimization for Chain of Trust (CoT) description + - bsec: Move bsec_mode_is_closed_device() service to platform + - cryptocell: Move Cryptocell specific API into driver + - gicv3: Prevent pending G1S interrupt from becoming G0 interrupt + - mbedtls: Remove weak heap implementation + - mmc: Increase delay between ACMD41 retries + - mmc: stm32_sdmmc2: Correctly manage block size + - mmc: stm32_sdmmc2: Manage max-frequency property from DT + - synopsys/emmc: Do not change FIFO TH as this breaks some platforms + - synopsys: Update synopsys drivers to not rely on undefined overflow + behaviour + - ufs: Extend the delay after reset to wait for some slower chips +- Platforms + - amlogic/meson/gxl: Remove BL2 dependency from BL31 + - arm/common: Shorten the Firmware Update (FWU) process + - arm/fvp: Remove GIC initialisation from secondary core cold boot + - arm/sgm: Temporarily disable shared Mbed TLS heap for SGM + - hisilicon: Update hisilicon drivers to not rely on undefined overflow + behaviour + - imx: imx8: Replace PLAT_IMX8\* with PLAT_imx8\*, remove duplicated linker + symbols and deprecated code include, keep only IRQ 32 unmasked, enable all + power domain by default + - marvell: Prevent SError accessing PCIe link, Switch to xlat_tables_v2, do + not rely on argument passed via smc, make sure that comphy init will use + correct address + - mediatek: mt8173: Refactor RTC and PMIC drivers + - mediatek: mt8173: Apply MULTI_CONSOLE framework + - nvidia: Tegra: memctrl_v2: fix "overflow before widen" coverity issue + - qemu: Simplify the image size calculation, Move and generalise FDT PSCI + fixup, move gicv2 codes to separate file + - renesas/rcar_gen3: Convert to multi-console API, update QoS setting, Update + IPL and Secure Monitor Rev2.0.4, Change to restore timer counter value at + resume, Update DDR setting rev.0.35, qos: change subslot cycle, Change + periodic write DQ training option. + - rockchip: Allow SOCs with undefined wfe check bits, Streamline and complete + UARTn_BASE macros, drop rockchip-specific imported linker symbols for bl31, + Disable binary generation for all SOCs, Allow console device to be set by + DTB, Use new bl31_params_parse functions + - rpi/rpi3: Move shared rpi3 files into common directory + - socionext/uniphier: Set CONSOLE_FLAG_TRANSLATE_CRLF and clean up console + driver + - socionext/uniphier: Replace DIV_ROUND_UP() with div_round_up() from + utils_def.h + - st/stm32mp: Split stm32mp_io_setup function, move + stm32_get_gpio_bank_clock() to private file, correctly handle Clock + Spreading Generator, move oscillator functions to generic file, realign + device tree files with internal devs, enable RTCAPB clock for dual-core + chips, use a common function to check spinlock is available, move + check_header() to common code + - ti/k3: Enable SEPARATE_CODE_AND_RODATA by default, Remove shared RAM space, + Drop \_ADDRESS from K3_USART_BASE to match other defines, Remove MSMC port + definitions, Allow USE_COHERENT_MEM for K3, Set L2 latency on A72 cores +- PSCI + - PSCI: Lookup list of parent nodes to lock only once +- Secure Partition Manager (SPM): SPCI Prototype + - Fix service UUID lookup + - Adjust size of virtual address space per partition + - Refactor xlat context creation + - Move shim layer to TTBR1_EL1 + - Ignore empty regions in resource description +- Security + - Refactor SPSR initialisation code + - SMMUv3: Abort DMA transactions + - For security DMA should be blocked at the SMMU by default unless + explicitly enabled for a device. SMMU is disabled after reset with all + streams bypassing the SMMU, and abortion of all incoming transactions + implements a default deny policy on reset. + - Moves `bl1_platform_setup()` function from arm_bl1_setup.c to FVP + platforms' fvp_bl1_setup.c and fvp_ve_bl1_setup.c files. +- Tools + - cert_create: Remove RSA PKCS#1 v1.5 support + +### Resolved Issues + +- Architecture + - Fix the CAS spinlock implementation by adding a missing DSB in + `spin_unlock()` + - AArch64: Fix SCTLR bit definitions + - Removes incorrect `SCTLR_V_BIT` definition and adds definitions for + ARMv8.3-Pauth `EnIB`, `EnDA` and `EnDB` bits. + - Fix restoration of PAuth context + - Replace call to `pauth_context_save()` with `pauth_context_restore()` in + case of unknown SMC call. +- BL-Specific Issues + - Fix BL31 crash reporting on AArch64 only platforms +- Build System + - Remove several warnings reported with W=2 and W=1 +- Code Quality Issues + - SCTLR and ACTLR are 32-bit for AArch32 and 64-bit for AArch64 + - Unify type of "cpu_idx" across PSCI module. + - Assert if power level value greater then PSCI_INVALID_PWR_LVL + - Unsigned long should not be used as per coding guidelines + - Reduce the number of memory leaks in cert_create + - Fix type of cot_desc_ptr + - Use explicit-width data types in AAPCS parameter structs + - Add python configuration for editorconfig + - BL1: Fix type consistency + - Enable -Wshift-overflow=2 to check for undefined shift behavior + - Updated upstream platforms to not rely on undefined overflow behaviour +- Coverity Quality Issues + - Remove GGC ignore -Warray-bounds + - Fix Coverity #261967, Infinite loop + - Fix Coverity #343017, Missing unlock + - Fix Coverity #343008, Side affect in assertion + - Fix Coverity #342970, Uninitialized scalar variable +- CPU Support + - cortex-a12: Fix MIDR mask +- Drivers + - console: Remove Arm console unregister on suspend + - gicv3: Fix support for full SPI range + - scmi: Fix wrong payload length +- Library Code + - libc: Fix sparse warning for \_\_assert() + - libc: Fix memchr implementation +- Platforms + - rpi: rpi3: Fix compilation error when stack protector is enabled + - socionext/uniphier: Fix compilation fail for SPM support build config + - st/stm32mp1: Fix TZC400 configuration against non-secure DDR + - ti/k3: common: Fix RO data area size calculation +- Security + - AArch32: Disable Secure Cycle Counter + - Changes the implementation for disabling Secure Cycle Counter. For ARMv8.5 + the counter gets disabled by setting `SDCR.SCCD` bit on CPU cold/warm + boot. For the earlier architectures PMCR register is saved/restored on + secure world entry/exit from/to Non-secure state, and cycle counting gets + disabled by setting PMCR.DP bit. + - AArch64: Disable Secure Cycle Counter + - For ARMv8.5 the counter gets disabled by setting `MDCR_El3.SCCD` bit on + CPU cold/warm boot. For the earlier architectures PMCR_EL0 register is + saved/restored on secure world entry/exit from/to Non-secure state, and + cycle counting gets disabled by setting PMCR_EL0.DP bit. + +### Deprecations + +- Common Code + - Remove MULTI_CONSOLE_API flag and references to it + - Remove deprecated `plat_crash_console_*` + - Remove deprecated interfaces `get_afflvl_shift`, `mpidr_mask_lower_afflvls`, + `eret` + - AARCH32/AARCH64 macros are now deprecated in favor of `__aarch64__` + - `__ASSEMBLY__` macro is now deprecated in favor of `__ASSEMBLER__` +- Drivers + - console: Removed legacy console API + - console: Remove deprecated finish_console_register + - tzc: Remove deprecated types `tzc_action_t` and `tzc_region_attributes_t` +- Secure Partition Manager (SPM): + - Prototype SPCI-based SPM (services/std_svc/spm) will be replaced with + alternative methods of secure partitioning support. + +### Known Issues + +- Build System Issues + - dtb: DTB creation not supported when building on a Windows host. + + This step in the build process is skipped when running on a Windows host. A + known issue from the 1.6 release. +- Platform Issues + - arm/juno: System suspend from Linux does not function as documented in the + user guide + + Following the instructions provided in the user guide document does not + result in the platform entering system suspend state as expected. A message + relating to the hdlcd driver failing to suspend will be emitted on the Linux + terminal. + + - mediatek/mt6795: This platform does not build in this release + +## 2.1 (2019-03-29) + +### New Features + +- Architecture + + - Support for ARMv8.3 pointer authentication in the normal and secure worlds + + The use of pointer authentication in the normal world is enabled whenever + architectural support is available, without the need for additional build + flags. + + Use of pointer authentication in the secure world remains an experimental + configuration at this time. Using both the `ENABLE_PAUTH` and + `CTX_INCLUDE_PAUTH_REGS` build flags, pointer authentication can be enabled + in EL3 and S-EL1/0. + + See the {ref}`Firmware Design` document for additional details on the use of + pointer authentication. + + - Enable Data Independent Timing (DIT) in EL3, where supported + +- Build System + + - Support for BL-specific build flags + + - Support setting compiler target architecture based on `ARM_ARCH_MINOR` build + option. + + - New `RECLAIM_INIT_CODE` build flag: + + A significant amount of the code used for the initialization of BL31 is not + needed again after boot time. In order to reduce the runtime memory + footprint, the memory used for this code can be reclaimed after + initialization. + + Certain boot-time functions were marked with the `__init` attribute to + enable this reclamation. + +- CPU Support + + - cortex-a76: Workaround for erratum 1073348 + - cortex-a76: Workaround for erratum 1220197 + - cortex-a76: Workaround for erratum 1130799 + - cortex-a75: Workaround for erratum 790748 + - cortex-a75: Workaround for erratum 764081 + - cortex-a73: Workaround for erratum 852427 + - cortex-a73: Workaround for erratum 855423 + - cortex-a57: Workaround for erratum 817169 + - cortex-a57: Workaround for erratum 814670 + - cortex-a55: Workaround for erratum 903758 + - cortex-a55: Workaround for erratum 846532 + - cortex-a55: Workaround for erratum 798797 + - cortex-a55: Workaround for erratum 778703 + - cortex-a55: Workaround for erratum 768277 + - cortex-a53: Workaround for erratum 819472 + - cortex-a53: Workaround for erratum 824069 + - cortex-a53: Workaround for erratum 827319 + - cortex-a17: Workaround for erratum 852423 + - cortex-a17: Workaround for erratum 852421 + - cortex-a15: Workaround for erratum 816470 + - cortex-a15: Workaround for erratum 827671 + +- Documentation + + - Exception Handling Framework documentation + - Library at ROM (romlib) documentation + - RAS framework documentation + - Coding Guidelines document + +- Drivers + + - ccn: Add API for setting and reading node registers + + - Adds `ccn_read_node_reg` function + - Adds `ccn_write_node_reg` function + + - partition: Support MBR partition entries + + - scmi: Add `plat_css_get_scmi_info` function + + Adds a new API `plat_css_get_scmi_info` which lets the platform register a + platform-specific instance of `scmi_channel_plat_info_t` and remove the + default values + + - tzc380: Add TZC-380 TrustZone Controller driver + + - tzc-dmc620: Add driver to manage the TrustZone Controller within the DMC-620 + Dynamic Memory Controller + +- Library at ROM (romlib) + + - Add platform-specific jump table list + + - Allow patching of romlib functions + + This change allows patching of functions in the romlib. This can be done by + adding "patch" at the end of the jump table entry for the function that + needs to be patched in the file jmptbl.i. + +- Library Code + + - Support non-LPAE-enabled MMU tables in AArch32 + - mmio: Add `mmio_clrsetbits_16` function + - 16-bit variant of `mmio_clrsetbits` + - object_pool: Add Object Pool Allocator + - Manages object allocation using a fixed-size static array + - Adds `pool_alloc` and `pool_alloc_n` functions + - Does not provide any functions to free allocated objects (by design) + - libc: Added `strlcpy` function + - libc: Import `strrchr` function from FreeBSD + - xlat_tables: Add support for ARMv8.4-TTST + - xlat_tables: Support mapping regions without an explicitly specified VA + +- Math + + - Added softudiv macro to support software division + +- Memory Partitioning And Monitoring (MPAM) + + - Enabled MPAM EL2 traps (`MPAMHCR_EL2` and `MPAM_EL2`) + +- Platforms + + - amlogic: Add support for Meson S905 (GXBB) + + - arm/fvp_ve: Add support for FVP Versatile Express platform + + - arm/n1sdp: Add support for Neoverse N1 System Development platform + + - arm/rde1edge: Add support for Neoverse E1 platform + + - arm/rdn1edge: Add support for Neoverse N1 platform + + - arm: Add support for booting directly to Linux without an intermediate + loader (AArch32) + + - arm/juno: Enable new CPU errata workarounds for A53 and A57 + + - arm/juno: Add romlib support + + Building a combined BL1 and ROMLIB binary file with the correct page + alignment is now supported on the Juno platform. When `USE_ROMLIB` is set + for Juno, it generates the combined file `bl1_romlib.bin` which needs to be + used instead of bl1.bin. + + - intel/stratix: Add support for Intel Stratix 10 SoC FPGA platform + + - marvell: Add support for Armada-37xx SoC platform + + - nxp: Add support for i.MX8M and i.MX7 Warp7 platforms + + - renesas: Add support for R-Car Gen3 platform + + - xilinx: Add support for Versal ACAP platforms + +- Position-Independent Executable (PIE) + + PIE support has initially been added to BL31. The `ENABLE_PIE` build flag is + used to enable or disable this functionality as required. + +- Secure Partition Manager + + - New SPM implementation based on SPCI Alpha 1 draft specification + + A new version of SPM has been implemented, based on the SPCI (Secure + Partition Client Interface) and SPRT (Secure Partition Runtime) draft + specifications. + + The new implementation is a prototype that is expected to undergo intensive + rework as the specifications change. It has basic support for multiple + Secure Partitions and Resource Descriptions. + + The older version of SPM, based on MM (ARM Management Mode Interface + Specification), is still present in the codebase. A new build flag, `SPM_MM` + has been added to allow selection of the desired implementation. This flag + defaults to 1, selecting the MM-based implementation. + +- Security + + - Spectre Variant-1 mitigations (`CVE-2017-5753`) + + - Use Speculation Store Bypass Safe (SSBS) functionality where available + + Provides mitigation against `CVE-2018-19440` (Not saving x0 to x3 registers + can leak information from one Normal World SMC client to another) + +### Changed + +- Build System + + - Warning levels are now selectable with `W=<1,2,3>` + - Removed unneeded include paths in PLAT_INCLUDES + - "Warnings as errors" (Werror) can be disabled using `E=0` + - Support totally quiet output with `-s` flag + - Support passing options to checkpatch using `CHECKPATCH_OPTS=` + - Invoke host compiler with `HOSTCC / HOSTCCFLAGS` instead of `CC / CFLAGS` + - Make device tree pre-processing similar to U-boot/Linux by: + - Creating separate `CPPFLAGS` for DT preprocessing so that compiler options + specific to it can be accommodated. + - Replacing `CPP` with `PP` for DT pre-processing + +- CPU Support + + - Errata report function definition is now mandatory for CPU support files + + CPU operation files must now define a `_errata_report` function to + print errata status. This is no longer a weak reference. + +- Documentation + + - Migrated some content from GitHub wiki to `docs/` directory + - Security advisories now have CVE links + - Updated copyright guidelines + +- Drivers + + - console: The `MULTI_CONSOLE_API` framework has been rewritten in C + + - console: Ported multi-console driver to AArch32 + + - gic: Remove 'lowest priority' constants + + Removed `GIC_LOWEST_SEC_PRIORITY` and `GIC_LOWEST_NS_PRIORITY`. Platforms + should define these if required, or instead determine the correct priority + values at runtime. + + - delay_timer: Check that the Generic Timer extension is present + + - mmc: Increase command reply timeout to 10 milliseconds + + - mmc: Poll eMMC device status to ensure `EXT_CSD` command completion + + - mmc: Correctly check return code from `mmc_fill_device_info` + +- External Libraries + + - libfdt: Upgraded from 1.4.2 to 1.4.6-9 + + > + + - mbed TLS: Upgraded from 2.12 to 2.16 + + > + + This change incorporates fixes for security issues that should be reviewed to + determine if they are relevant for software implementations using Trusted + Firmware-A. See the [mbed TLS releases] page for details on changes from the + 2.12 to the 2.16 release. + +- Library Code + + - compiler-rt: Updated `lshrdi3.c` and `int_lib.h` with changes from LLVM + master branch (r345645) + - cpu: Updated macro that checks need for `CVE-2017-5715` mitigation + - libc: Made setjmp and longjmp C standard compliant + - libc: Allowed overriding the default libc (use `OVERRIDE_LIBC`) + - libc: Moved setjmp and longjmp to the `libc/` directory + +- Platforms + + - Removed Mbed TLS dependency from plat_bl_common.c + + - arm: Removed unused `ARM_MAP_BL_ROMLIB` macro + + - arm: Removed `ARM_BOARD_OPTIMISE_MEM` feature and build flag + + - arm: Moved several components into `drivers/` directory + + This affects the SDS, SCP, SCPI, MHU and SCMI components + + - arm/juno: Increased maximum BL2 image size to `0xF000` + + This change was required to accommodate a larger `libfdt` library + +- SCMI + + - Optimized bakery locks when hardware-assisted coherency is enabled using the + `HW_ASSISTED_COHERENCY` build flag + +- SDEI + + - Added support for unconditionally resuming secure world execution after {{ + SDEI }} event processing completes + + {{ SDEI }} interrupts, although targeting EL3, occur on behalf of the + non-secure world, and may have higher priority than secure world interrupts. + Therefore they might preempt secure execution and yield execution to the + non-secure {{ SDEI }} handler. Upon completion of {{ SDEI }} event handling, + resume secure execution if it was preempted. + +- Translation Tables (XLAT) + + - Dynamically detect need for `Common not Private (TTBRn_ELx.CnP)` bit + + Properly handle the case where `ARMv8.2-TTCNP` is implemented in a CPU that + does not implement all mandatory v8.2 features (and so must claim to + implement a lower architecture version). + +### Resolved Issues + +- Architecture + - Incorrect check for SSBS feature detection + - Unintentional register clobber in AArch32 reset_handler function +- Build System + - Dependency issue during DTB image build + - Incorrect variable expansion in Arm platform makefiles + - Building on Windows with verbose mode (`V=1`) enabled is broken + - AArch32 compilation flags is missing `$(march32-directive)` +- BL-Specific Issues + - bl2: `uintptr_t is not defined` error when `BL2_IN_XIP_MEM` is defined + - bl2: Missing prototype warning in `bl2_arch_setup` + - bl31: Omission of Global Offset Table (GOT) section +- Code Quality Issues + - Multiple MISRA compliance issues + - Potential NULL pointer dereference (Coverity-detected) +- Drivers + - mmc: Local declaration of `scr` variable causes a cache issue when + invalidating after the read DMA transfer completes + - mmc: `ACMD41` does not send voltage information during initialization, + resulting in the command being treated as a query. This prevents the command + from initializing the controller. + - mmc: When checking device state using `mmc_device_state()` there are no + retries attempted in the event of an error + - ccn: Incorrect Region ID calculation for RN-I nodes + - console: `Fix MULTI_CONSOLE_API` when used as a crash console + - partition: Improper NULL checking in gpt.c + - partition: Compilation failure in `VERBOSE` mode (`V=1`) +- Library Code + - common: Incorrect check for Address Authentication support + + - xlat: Fix XLAT_V1 / XLAT_V2 incompatibility + + The file `arm_xlat_tables.h` has been renamed to `xlat_tables_compat.h` and + has been moved to a common folder. This header can be used to guarantee + compatibility, as it includes the correct header based on + `XLAT_TABLES_LIB_V2`. + + - xlat: armclang unused-function warning on `xlat_clean_dcache_range` + + - xlat: Invalid `mm_cursor` checks in `mmap_add` and `mmap_add_ctx` + + - sdei: Missing `context.h` header +- Platforms + - common: Missing prototype warning for `plat_log_get_prefix` + + - arm: Insufficient maximum BL33 image size + + - arm: Potential memory corruption during BL2-BL31 transition + + On Arm platforms, the BL2 memory can be overlaid by BL31/BL32. The memory + descriptors describing the list of executable images are created in BL2 R/W + memory, which could be possibly corrupted later on by BL31/BL32 due to + overlay. This patch creates a reserved location in SRAM for these + descriptors and are copied over by BL2 before handing over to next BL image. + + - juno: Invalid behaviour when `CSS_USE_SCMI_SDS_DRIVER` is not set + + In `juno_pm.c` the `css_scmi_override_pm_ops` function was used regardless + of whether the build flag was set. The original behaviour has been restored + in the case where the build flag is not set. +- Tools + - fiptool: Incorrect UUID parsing of blob parameters + - doimage: Incorrect object rules in Makefile + +### Deprecations + +- Common Code + - `plat_crash_console_init` function + - `plat_crash_console_putc` function + - `plat_crash_console_flush` function + - `finish_console_register` macro +- AArch64-specific Code + - helpers: `get_afflvl_shift` + - helpers: `mpidr_mask_lower_afflvls` + - helpers: `eret` +- Secure Partition Manager (SPM) + - Boot-info structure + +### Known Issues + +- Build System Issues + - dtb: DTB creation not supported when building on a Windows host. + + This step in the build process is skipped when running on a Windows host. A + known issue from the 1.6 release. +- Platform Issues + - arm/juno: System suspend from Linux does not function as documented in the + user guide + + Following the instructions provided in the user guide document does not + result in the platform entering system suspend state as expected. A message + relating to the hdlcd driver failing to suspend will be emitted on the Linux + terminal. + + - arm/juno: The firmware update use-cases do not work with motherboard + firmware version \< v1.5.0 (the reset reason is not preserved). The Linaro + 18.04 release has MB v1.4.9. The MB v1.5.0 is available in Linaro 18.10 + release. + + - mediatek/mt6795: This platform does not build in this release + +## 2.0 (2018-10-02) + +### New Features + +- Removal of a number of deprecated APIs + + - A new Platform Compatibility Policy document has been created which + references a wiki page that maintains a listing of deprecated interfaces and + the release after which they will be removed. + - All deprecated interfaces except the MULTI_CONSOLE_API have been removed + from the code base. + - Various Arm and partner platforms have been updated to remove the use of + removed APIs in this release. + - This release is otherwise unchanged from 1.6 release + +### Issues resolved since last release + +- No issues known at 1.6 release resolved in 2.0 release + +### Known Issues + +- DTB creation not supported when building on a Windows host. This step in the + build process is skipped when running on a Windows host. Known issue from 1.6 + version. +- As a result of removal of deprecated interfaces the Nvidia Tegra, Marvell + Armada 8K and MediaTek MT6795 platforms do not build in this release. Also + MediaTek MT8173, NXP QorIQ LS1043A, NXP i.MX8QX, NXP i.MX8QMa, Rockchip + RK3328, Rockchip RK3368 and Rockchip RK3399 platforms have not been confirmed + to be working after the removal of the deprecated interfaces although they do + build. + +## 1.6 (2018-09-21) + +### New Features + +- Addressing Speculation Security Vulnerabilities + + - Implement static workaround for CVE-2018-3639 for AArch32 and AArch64 + - Add support for dynamic mitigation for CVE-2018-3639 + - Implement dynamic mitigation for CVE-2018-3639 on Cortex-A76 + - Ensure {{ SDEI }} handler executes with CVE-2018-3639 mitigation enabled + +- Introduce RAS handling on AArch64 + + - Some RAS extensions are mandatory for Armv8.2 CPUs, with others mandatory + for Armv8.4 CPUs however, all extensions are also optional extensions to the + base Armv8.0 architecture. + - The Armv8 RAS Extensions introduced Standard Error Records which are a set + of standard registers to configure RAS node policy and allow RAS Nodes to + record and expose error information for error handling agents. + - Capabilities are provided to support RAS Node enumeration and iteration + along with individual interrupt registrations and fault injections support. + - Introduce handlers for Uncontainable errors, Double Faults and EL3 External + Aborts + +- Enable Memory Partitioning And Monitoring (MPAM) for lower EL's + + - Memory Partitioning And Monitoring is an Armv8.4 feature that enables + various memory system components and resources to define partitions. + Software running at various ELs can then assign themselves to the desired + partition to control their performance aspects. + - When ENABLE_MPAM_FOR_LOWER_ELS is set to 1, EL3 allows lower ELs to access + their own MPAM registers without trapping to EL3. This patch however, + doesn't make use of partitioning in EL3; platform initialisation code should + configure and use partitions in EL3 if required. + +- Introduce ROM Lib Feature + + - Support combining several libraries into a self-called "romlib" image, that + may be shared across images to reduce memory footprint. The romlib image is + stored in ROM but is accessed through a jump-table that may be stored in + read-write memory, allowing for the library code to be patched. + +- Introduce Backtrace Feature + + - This function displays the backtrace, the current EL and security state to + allow a post-processing tool to choose the right binary to interpret the + dump. + - Print backtrace in assert() and panic() to the console. + +- Code hygiene changes and alignment with MISRA C-2012 guideline with fixes + addressing issues complying to the following rules: + + - MISRA rules 4.9, 5.1, 5.3, 5.7, 8.2-8.5, 8.8, 8.13, 9.3, 10.1, 10.3-10.4, + 10.8, 11.3, 11.6, 12.1, 14.4, 15.7, 16.1-16.7, 17.7-17.8, 20.7, 20.10, + 20.12, 21.1, 21.15, 22.7 + - Clean up the usage of void pointers to access symbols + - Increase usage of static qualifier to locally used functions and data + - Migrated to use of u_register_t for register read/write to better match + AArch32 and AArch64 type sizes + - Use int-ll64 for both AArch32 and AArch64 to assist in consistent format + strings between architectures + - Clean up TF-A libc by removing non arm copyrighted implementations and + replacing them with modified FreeBSD and SCC implementations + +- Various changes to support Clang linker and assembler + + - The clang assembler/preprocessor is used when Clang is selected. However, + the clang linker is not used because it is unable to link TF-A objects due + to immaturity of clang linker functionality at this time. + +- Refactor support APIs into Libraries + + - Evolve libfdt, mbed TLS library and standard C library sources as proper + libraries that TF-A may be linked against. + +- CPU Enhancements + + - Add CPU support for Cortex-Ares and Cortex-A76 + - Add AMU support for Cortex-Ares + - Add initial CPU support for Cortex-Deimos + - Add initial CPU support for Cortex-Helios + - Implement dynamic mitigation for CVE-2018-3639 on Cortex-A76 + - Implement Cortex-Ares erratum 1043202 workaround + - Implement DSU erratum 936184 workaround + - Check presence of fix for errata 843419 in Cortex-A53 + - Check presence of fix for errata 835769 in Cortex-A53 + +- Translation Tables Enhancements + + - The xlat v2 library has been refactored in order to be reused by different + TF components at different EL's including the addition of EL2. Some + refactoring to make the code more generic and less specific to TF, in order + to reuse the library outside of this project. + +- SPM Enhancements + + - General cleanups and refactoring to pave the way to multiple partitions + support + +- SDEI Enhancements + + - Allow platforms to define explicit events + - Determine client EL from NS context's SCR_EL3 + - Make dispatches synchronous + - Introduce jump primitives for BL31 + - Mask events after CPU wakeup in {{ SDEI }} dispatcher to conform to the + specification + +- Misc TF-A Core Common Code Enhancements + + - Add support for eXecute In Place (XIP) memory in BL2 + - Add support for the SMC Calling Convention 2.0 + - Introduce External Abort handling on AArch64 External Abort routed to EL3 + was reported as an unhandled exception and caused a panic. This change + enables Trusted Firmware-A to handle External Aborts routed to EL3. + - Save value of ACTLR_EL1 implementation-defined register in the CPU context + structure rather than forcing it to 0. + - Introduce ARM_LINUX_KERNEL_AS_BL33 build option, which allows BL31 to + directly jump to a Linux kernel. This makes for a quicker and simpler boot + flow, which might be useful in some test environments. + - Add dynamic configurations for BL31, BL32 and BL33 enabling support for + Chain of Trust (COT). + - Make TF UUID RFC 4122 compliant + +- New Platform Support + + - Arm SGI-575 + - Arm SGM-775 + - Allwinner sun50i_64 + - Allwinner sun50i_h6 + - NXP QorIQ LS1043A + - NXP i.MX8QX + - NXP i.MX8QM + - NXP i.MX7Solo WaRP7 + - TI K3 + - Socionext Synquacer SC2A11 + - Marvell Armada 8K + - STMicroelectronics STM32MP1 + +- Misc Generic Platform Common Code Enhancements + + - Add MMC framework that supports both eMMC and SD card devices + +- Misc Arm Platform Common Code Enhancements + + - Demonstrate PSCI MEM_PROTECT from el3_runtime + - Provide RAS support + - Migrate AArch64 port to the multi console driver. The old API is deprecated + and will eventually be removed. + - Move BL31 below BL2 to enable BL2 overlay resulting in changes in the layout + of BL images in memory to enable more efficient use of available space. + - Add cpp build processing for dtb that allows processing device tree with + external includes. + - Extend FIP io driver to support multiple FIP devices + - Add support for SCMI AP core configuration protocol v1.0 + - Use SCMI AP core protocol to set the warm boot entrypoint + - Add support to Mbed TLS drivers for shared heap among different BL images to + help optimise memory usage + - Enable non-secure access to UART1 through a build option to support a serial + debug port for debugger connection + +- Enhancements for Arm Juno Platform + + - Add support for TrustZone Media Protection 1 (TZMP1) + +- Enhancements for Arm FVP Platform + + - Dynamic_config: remove the FVP dtb files + - Set DYNAMIC_WORKAROUND_CVE_2018_3639=1 on FVP by default + - Set the ability to dynamically disable Trusted Boot Board authentication to + be off by default with DYN_DISABLE_AUTH + - Add librom enhancement support in FVP + - Support shared Mbed TLS heap between BL1 and BL2 that allow a reduction in + BL2 size for FVP + +- Enhancements for Arm SGI/SGM Platform + + - Enable ARM_PLAT_MT flag for SGI-575 + - Add dts files to enable support for dynamic config + - Add RAS support + - Support shared Mbed TLS heap for SGI and SGM between BL1 and BL2 + +- Enhancements for Non Arm Platforms + + - Raspberry Pi Platform + - Hikey Platforms + - Xilinx Platforms + - QEMU Platform + - Rockchip rk3399 Platform + - TI Platforms + - Socionext Platforms + - Allwinner Platforms + - NXP Platforms + - NVIDIA Tegra Platform + - Marvell Platforms + - STMicroelectronics STM32MP1 Platform + +### Issues resolved since last release + +- No issues known at 1.5 release resolved in 1.6 release + +### Known Issues + +- DTB creation not supported when building on a Windows host. This step in the + build process is skipped when running on a Windows host. Known issue from 1.5 + version. + +## 1.5 (2018-03-20) + +### New features + +- Added new firmware support to enable RAS (Reliability, Availability, and + Serviceability) functionality. + + - Secure Partition Manager (SPM): A Secure Partition is a software execution + environment instantiated in S-EL0 that can be used to implement simple + management and security services. The SPM is the firmware component that is + responsible for managing a Secure Partition. + + - SDEI dispatcher: Support for interrupt-based {{ SDEI }} events and all + interfaces as defined by the {{ SDEI }} specification v1.0, see + [SDEI Specification] + + - Exception Handling Framework (EHF): Framework that allows dispatching of EL3 + interrupts to their registered handlers which are registered based on their + priorities. Facilitates firmware-first error handling policy where + asynchronous exceptions may be routed to EL3. + + Integrated the TSPD with EHF. + +- Updated PSCI support: + + - Implemented PSCI v1.1 optional features `MEM_PROTECT` and `SYSTEM_RESET2`. + The supported PSCI version was updated to v1.1. + + - Improved PSCI STAT timestamp collection, including moving accounting for + retention states to be inside the locks and fixing handling of wrap-around + when calculating residency in AArch32 execution state. + + - Added optional handler for early suspend that executes when suspending to a + power-down state and with data caches enabled. + + This may provide a performance improvement on platforms where it is safe to + perform some or all of the platform actions from `pwr_domain_suspend` with + the data caches enabled. + +- Enabled build option, BL2_AT_EL3, for BL2 to allow execution at EL3 without + any dependency on TF BL1. + + This allows platforms which already have a non-TF Boot ROM to directly load + and execute BL2 and subsequent BL stages without need for BL1. This was not + previously possible because BL2 executes at S-EL1 and cannot jump straight to + EL3. + +- Implemented support for SMCCC v1.1, including `SMCCC_VERSION` and + `SMCCC_ARCH_FEATURES`. + + Additionally, added support for `SMCCC_VERSION` in PSCI features to enable + discovery of the SMCCC version via PSCI feature call. + +- Added Dynamic Configuration framework which enables each of the boot loader + stages to be dynamically configured at runtime if required by the platform. + The boot loader stage may optionally specify a firmware configuration file + and/or hardware configuration file that can then be shared with the next boot + loader stage. + + Introduced a new BL handover interface that essentially allows passing of 4 + arguments between the different BL stages. + + Updated cert_create and fip_tool to support the dynamic configuration files. + The COT also updated to support these new files. + +- Code hygiene changes and alignment with MISRA guideline: + + - Fix use of undefined macros. + - Achieved compliance with Mandatory MISRA coding rules. + - Achieved compliance for following Required MISRA rules for the default build + configurations on FVP and Juno platforms : 7.3, 8.3, 8.4, 8.5 and 8.8. + +- Added support for Armv8.2-A architectural features: + + - Updated translation table set-up to set the CnP (Common not Private) bit for + secure page tables so that multiple PEs in the same Inner Shareable domain + can use the same translation table entries for a given stage of translation + in a particular translation regime. + - Extended the supported values of ID_AA64MMFR0_EL1.PARange to include the + 52-bit Physical Address range. + - Added support for the Scalable Vector Extension to allow Normal world + software to access SVE functionality but disable access to SVE, SIMD and + floating point functionality from the Secure world in order to prevent + corruption of the Z-registers. + +- Added support for Armv8.4-A architectural feature Activity Monitor Unit (AMU) + + extensions. + + In addition to the v8.4 architectural extension, AMU support on Cortex-A75 was + implemented. + +- Enhanced OP-TEE support to enable use of pageable OP-TEE image. The Arm + standard platforms are updated to load up to 3 images for OP-TEE; header, + pager image and paged image. + + The chain of trust is extended to support the additional images. + +- Enhancements to the translation table library: + + - Introduced APIs to get and set the memory attributes of a region. + - Added support to manage both privilege levels in translation regimes that + describe translations for 2 Exception levels, specifically the EL1&0 + translation regime, and extended the memory map region attributes to include + specifying Non-privileged access. + - Added support to specify the granularity of the mappings of each region, for + instance a 2MB region can be specified to be mapped with 4KB page tables + instead of a 2MB block. + - Disabled the higher VA range to avoid unpredictable behaviour if there is an + attempt to access addresses in the higher VA range. + - Added helpers for Device and Normal memory MAIR encodings that align with + the Arm Architecture Reference Manual for Armv8-A (Arm DDI0487B.b). + - Code hygiene including fixing type length and signedness of constants, + refactoring of function to enable the MMU, removing all instances where the + virtual address space is hardcoded and added comments that document + alignment needed between memory attributes and attributes specified in + TCR_ELx. + +- Updated GIC support: + + - Introduce new APIs for GICv2 and GICv3 that provide the capability to + specify interrupt properties rather than list of interrupt numbers alone. + The Arm platforms and other upstream platforms are migrated to use interrupt + properties. + + - Added helpers to save / restore the GICv3 context, specifically the + Distributor and Redistributor contexts and architectural parts of the ITS + power management. The Distributor and Redistributor helpers also support the + implementation-defined part of GIC-500 and GIC-600. + + Updated the Arm FVP platform to save / restore the GICv3 context on system + suspend / resume as an example of how to use the helpers. + + Introduced a new TZC secured DDR carve-out for use by Arm platforms for + storing EL3 runtime data such as the GICv3 register context. + +- Added support for Armv7-A architecture via build option ARM_ARCH_MAJOR=7. This + includes following features: + + - Updates GICv2 driver to manage GICv1 with security extensions. + - Software implementation for 32bit division. + - Enabled use of generic timer for platforms that do not set + ARM_CORTEX_Ax=yes. + - Support for Armv7-A Virtualization extensions \[DDI0406C_C\]. + - Support for both Armv7-A platforms that only have 32-bit addressing and + Armv7-A platforms that support large page addressing. + - Included support for following Armv7 CPUs: Cortex-A12, Cortex-A17, + Cortex-A7, Cortex-A5, Cortex-A9, Cortex-A15. + - Added support in QEMU for Armv7-A/Cortex-A15. + +- Enhancements to Firmware Update feature: + + - Updated the FWU documentation to describe the additional images needed for + Firmware update, and how they are used for both the Juno platform and the + Arm FVP platforms. + +- Enhancements to Trusted Board Boot feature: + + - Added support to cert_create tool for RSA PKCS1# v1.5 and SHA384, SHA512 and + SHA256. + - For Arm platforms added support to use ECDSA keys. + - Enhanced the mbed TLS wrapper layer to include support for both RSA and + ECDSA to enable runtime selection between RSA and ECDSA keys. + +- Added support for secure interrupt handling in AArch32 sp_min, hardcoded to + only handle FIQs. + +- Added support to allow a platform to load images from multiple boot sources, + for example from a second flash drive. + +- Added a logging framework that allows platforms to reduce the logging level at + runtime and additionally the prefix string can be defined by the platform. + +- Further improvements to register initialisation: + + - Control register PMCR_EL0 / PMCR is set to prohibit cycle counting in the + secure world. This register is added to the list of registers that are saved + and restored during world switch. + - When EL3 is running in AArch32 execution state, the Non-secure version of + SCTLR is explicitly initialised during the warmboot flow rather than relying + on the hardware to set the correct reset values. + +- Enhanced support for Arm platforms: + + - Introduced driver for Shared-Data-Structure (SDS) framework which is used + for communication between SCP and the AP CPU, replacing Boot-Over_MHU (BOM) + protocol. + + The Juno platform is migrated to use SDS with the SCMI support added in v1.3 + and is set as default. + + The driver can be found in the plat/arm/css/drivers folder. + + - Improved memory usage by only mapping TSP memory region when the TSPD has + been included in the build. This reduces the memory footprint and avoids + unnecessary memory being mapped. + + - Updated support for multi-threading CPUs for FVP platforms - always check + the MT field in MPDIR and access the bit fields accordingly. + + - Support building for platforms that model DynamIQ configuration by + implementing all CPUs in a single cluster. + + - Improved nor flash driver, for instance clearing status registers before + sending commands. Driver can be found plat/arm/board/common folder. + +- Enhancements to QEMU platform: + + - Added support for TBB. + - Added support for using OP-TEE pageable image. + - Added support for LOAD_IMAGE_V2. + - Migrated to use translation table library v2 by default. + - Added support for SEPARATE_CODE_AND_RODATA. + +- Applied workarounds CVE-2017-5715 on Arm Cortex-A57, -A72, -A73 and -A75, and + for Armv7-A CPUs Cortex-A9, -A15 and -A17. + +- Applied errata workaround for Arm Cortex-A57: 859972. + +- Applied errata workaround for Arm Cortex-A72: 859971. + +- Added support for Poplar 96Board platform. + +- Added support for Raspberry Pi 3 platform. + +- Added Call Frame Information (CFI) assembler directives to the vector entries + which enables debuggers to display the backtrace of functions that triggered a + synchronous abort. + +- Added ability to build dtb. + +- Added support for pre-tool (cert_create and fiptool) image processing enabling + compression of the image files before processing by cert_create and fiptool. + + This can reduce fip size and may also speed up loading of images. The image + verification will also get faster because certificates are generated based on + compressed images. + + Imported zlib 1.2.11 to implement gunzip() for data compression. + +- Enhancements to fiptool: + + - Enabled the fiptool to be built using Visual Studio. + - Added padding bytes at the end of the last image in the fip to be facilitate + transfer by DMA. + +### Issues resolved since last release + +- TF-A can be built with optimisations disabled (-O0). +- Memory layout updated to enable Trusted Board Boot on Juno platform when + running TF-A in AArch32 execution mode (resolving [tf-issue#501]). + +### Known Issues + +- DTB creation not supported when building on a Windows host. This step in the + build process is skipped when running on a Windows host. + +## 1.4 (2017-07-07) + +### New features + +- Enabled support for platforms with hardware assisted coherency. + + A new build option HW_ASSISTED_COHERENCY allows platforms to take advantage of + the following optimisations: + + - Skip performing cache maintenance during power-up and power-down. + - Use spin-locks instead of bakery locks. + - Enable data caches early on warm-booted CPUs. + +- Added support for Cortex-A75 and Cortex-A55 processors. + + Both Cortex-A75 and Cortex-A55 processors use the Arm DynamIQ Shared Unit + (DSU). The power-down and power-up sequences are therefore mostly managed in + hardware, reducing complexity of the software operations. + +- Introduced Arm GIC-600 driver. + + Arm GIC-600 IP complies with Arm GICv3 architecture. For FVP platforms, the + GIC-600 driver is chosen when FVP_USE_GIC_DRIVER is set to FVP_GIC600. + +- Updated GICv3 support: + + - Introduced power management APIs for GICv3 Redistributor. These APIs allow + platforms to power down the Redistributor during CPU power on/off. Requires + the GICv3 implementations to have power management operations. + + Implemented the power management APIs for FVP. + + - GIC driver data is flushed by the primary CPU so that secondary CPU do not + read stale GIC data. + +- Added support for Arm System Control and Management Interface v1.0 (SCMI). + + The SCMI driver implements the power domain management and system power + management protocol of the SCMI specification (Arm DEN 0056ASCMI) for + communicating with any compliant power controller. + + Support is added for the Juno platform. The driver can be found in the + plat/arm/css/drivers folder. + +- Added support to enable pre-integration of TBB with the Arm TrustZone + CryptoCell product, to take advantage of its hardware Root of Trust and crypto + acceleration services. + +- Enabled Statistical Profiling Extensions for lower ELs. + + The firmware support is limited to the use of SPE in the Non-secure state and + accesses to the SPE specific registers from S-EL1 will trap to EL3. + + The SPE are architecturally specified for AArch64 only. + +- Code hygiene changes aligned with MISRA guidelines: + + - Fixed signed / unsigned comparison warnings in the translation table + library. + - Added U(\_x) macro and together with the existing ULL(\_x) macro fixed some + of the signed-ness defects flagged by the MISRA scanner. + +- Enhancements to Firmware Update feature: + + - The FWU logic now checks for overlapping images to prevent execution of + unauthenticated arbitrary code. + - Introduced new FWU_SMC_IMAGE_RESET SMC that changes the image loading state + machine to go from COPYING, COPIED or AUTHENTICATED states to RESET state. + Previously, this was only possible when the authentication of an image + failed or when the execution of the image finished. + - Fixed integer overflow which addressed TFV-1: Malformed Firmware Update SMC + can result in copy of unexpectedly large data into secure memory. + +- Introduced support for Arm Compiler 6 and LLVM (clang). + + TF-A can now also be built with the Arm Compiler 6 or the clang compilers. The + assembler and linker must be provided by the GNU toolchain. + + Tested with Arm CC 6.7 and clang 3.9.x and 4.0.x. + +- Memory footprint improvements: + + - Introduced `tf_snprintf`, a reduced version of `snprintf` which has support + for a limited set of formats. + + The mbedtls driver is updated to optionally use `tf_snprintf` instead of + `snprintf`. + + - The `assert()` is updated to no longer print the function name, and + additional logging options are supported via an optional platform define + `PLAT_LOG_LEVEL_ASSERT`, which controls how verbose the assert output is. + +- Enhancements to TF-A support when running in AArch32 execution state: + + - Support booting SP_MIN and BL33 in AArch32 execution mode on Juno. Due to + hardware limitations, BL1 and BL2 boot in AArch64 state and there is + additional trampoline code to warm reset into SP_MIN in AArch32 execution + state. + - Added support for Arm Cortex-A53/57/72 MPCore processors including the + errata workarounds that are already implemented for AArch64 execution state. + - For FVP platforms, added AArch32 Trusted Board Boot support, including the + Firmware Update feature. + +- Introduced Arm SiP service for use by Arm standard platforms. + + - Added new Arm SiP Service SMCs to enable the Non-secure world to read PMF + timestamps. + + Added PMF instrumentation points in TF-A in order to quantify the overall + time spent in the PSCI software implementation. + + - Added new Arm SiP service SMC to switch execution state. + + This allows the lower exception level to change its execution state from + AArch64 to AArch32, or vice verse, via a request to EL3. + +- Migrated to use SPDX\[0\] license identifiers to make software license + auditing simpler. + + \:::\{note} Files that have been imported by FreeBSD have not been modified. + \::: + + \[0\]: + +- Enhancements to the translation table library: + + - Added version 2 of translation table library that allows different + translation tables to be modified by using different 'contexts'. Version 1 + of the translation table library only allows the current EL's translation + tables to be modified. + + Version 2 of the translation table also added support for dynamic regions; + regions that can be added and removed dynamically whilst the MMU is enabled. + Static regions can only be added or removed before the MMU is enabled. + + The dynamic mapping functionality is enabled or disabled when compiling by + setting the build option PLAT_XLAT_TABLES_DYNAMIC to 1 or 0. This can be + done per-image. + + - Added support for translation regimes with two virtual address spaces such + as the one shared by EL1 and EL0. + + The library does not support initializing translation tables for EL0 + software. + + - Added support to mark the translation tables as non-cacheable using an + additional build option `XLAT_TABLE_NC`. + +- Added support for GCC stack protection. A new build option + ENABLE_STACK_PROTECTOR was introduced that enables compilation of all BL + images with one of the GCC -fstack-protector-\* options. + + A new platform function plat_get_stack_protector_canary() was introduced that + returns a value used to initialize the canary for stack corruption detection. + For increased effectiveness of protection platforms must provide an + implementation that returns a random value. + +- Enhanced support for Arm platforms: + + - Added support for multi-threading CPUs, indicated by `MT` field in MPDIR. A + new build flag `ARM_PLAT_MT` is added, and when enabled, the functions + accessing MPIDR assume that the `MT` bit is set for the platform and access + the bit fields accordingly. + + Also, a new API `plat_arm_get_cpu_pe_count` is added when `ARM_PLAT_MT` is + enabled, returning the Processing Element count within the physical CPU + corresponding to `mpidr`. + + - The Arm platforms migrated to use version 2 of the translation tables. + + - Introduced a new Arm platform layer API `plat_arm_psci_override_pm_ops` + which allows Arm platforms to modify `plat_arm_psci_pm_ops` and therefore + dynamically define PSCI capability. + + - The Arm platforms migrated to use IMAGE_LOAD_V2 by default. + +- Enhanced reporting of errata workaround status with the following policy: + + - If an errata workaround is enabled: + + - If it applies (i.e. the CPU is affected by the errata), an INFO message is + printed, confirming that the errata workaround has been applied. + - If it does not apply, a VERBOSE message is printed, confirming that the + errata workaround has been skipped. + + - If an errata workaround is not enabled, but would have applied had it been, + a WARN message is printed, alerting that errata workaround is missing. + +- Added build options ARM_ARCH_MAJOR and ARM_ARM_MINOR to choose the + architecture version to target TF-A. + +- Updated the spin lock implementation to use the more efficient CAS (Compare + And Swap) instruction when available. This instruction was introduced in + Armv8.1-A. + +- Applied errata workaround for Arm Cortex-A53: 855873. + +- Applied errata workaround for Arm-Cortex-A57: 813419. + +- Enabled all A53 and A57 errata workarounds for Juno, both in AArch64 and + AArch32 execution states. + +- Added support for Socionext UniPhier SoC platform. + +- Added support for Hikey960 and Hikey platforms. + +- Added support for Rockchip RK3328 platform. + +- Added support for NVidia Tegra T186 platform. + +- Added support for Designware emmc driver. + +- Imported libfdt v1.4.2 that addresses buffer overflow in fdt_offset_ptr(). + +- Enhanced the CPU operations framework to allow power handlers to be registered + on per-level basis. This enables support for future CPUs that have multiple + threads which might need powering down individually. + +- Updated register initialisation to prevent unexpected behaviour: + + - Debug registers MDCR-EL3/SDCR and MDCR_EL2/HDCR are initialised to avoid + unexpected traps into the higher exception levels and disable secure + self-hosted debug. Additionally, secure privileged external debug on Juno is + disabled by programming the appropriate Juno SoC registers. + - EL2 and EL3 configurable controls are initialised to avoid unexpected traps + in the higher exception levels. + - Essential control registers are fully initialised on EL3 start-up, when + initialising the non-secure and secure context structures and when preparing + to leave EL3 for a lower EL. This gives better alignment with the Arm ARM + which states that software must initialise RES0 and RES1 fields with 0 / 1. + +- Enhanced PSCI support: + + - Introduced new platform interfaces that decouple PSCI stat residency + calculation from PMF, enabling platforms to use alternative methods of + capturing timestamps. + - PSCI stat accounting performed for retention/standby states when requested + at multiple power levels. + +- Simplified fiptool to have a single linked list of image descriptors. + +- For the TSP, resolved corruption of pre-empted secure context by aborting any + pre-empted SMC during PSCI power management requests. + +### Issues resolved since last release + +- TF-A can be built with the latest mbed TLS version (v2.4.2). The earlier + version 2.3.0 cannot be used due to build warnings that the TF-A build system + interprets as errors. +- TBBR, including the Firmware Update feature is now supported on FVP platforms + when running TF-A in AArch32 state. +- The version of the AEMv8 Base FVP used in this release has resolved the issue + of the model executing a reset instead of terminating in response to a + shutdown request using the PSCI SYSTEM_OFF API. + +### Known Issues + +- Building TF-A with compiler optimisations disabled (-O0) fails. +- Trusted Board Boot currently does not work on Juno when running Trusted + Firmware in AArch32 execution state due to error when loading the sp_min to + memory because of lack of free space available. See [tf-issue#501] for more + details. +- The errata workaround for A53 errata 843419 is only available from binutils + 2.26 and is not present in GCC4.9. If this errata is applicable to the + platform, please use GCC compiler version of at least 5.0. See [PR#1002] for + more details. + +## 1.3 (2016-10-13) + +### New features + +- Added support for running TF-A in AArch32 execution state. + + The PSCI library has been refactored to allow integration with **EL3 Runtime + Software**. This is software that is executing at the highest secure privilege + which is EL3 in AArch64 or Secure SVC/Monitor mode in AArch32. See + \{ref}`PSCI Library Integration guide for Armv8-A AArch32 systems`. + + Included is a minimal AArch32 Secure Payload, **SP-MIN**, that illustrates the + usage and integration of the PSCI library with EL3 Runtime Software running in + AArch32 state. + + Booting to the BL1/BL2 images as well as booting straight to the Secure + Payload is supported. + +- Improvements to the initialization framework for the PSCI service and Arm + Standard Services in general. + + The PSCI service is now initialized as part of Arm Standard Service + initialization. This consolidates the initializations of any Arm Standard + Service that may be added in the future. + + A new function `get_arm_std_svc_args()` is introduced to get arguments + corresponding to each standard service and must be implemented by the EL3 + Runtime Software. + + For PSCI, a new versioned structure `psci_lib_args_t` is introduced to + initialize the PSCI Library. **Note** this is a compatibility break due to the + change in the prototype of `psci_setup()`. + +- To support AArch32 builds of BL1 and BL2, implemented a new, alternative + firmware image loading mechanism that adds flexibility. + + The current mechanism has a hard-coded set of images and execution order + (BL31, BL32, etc). The new mechanism is data-driven by a list of image + descriptors provided by the platform code. + + Arm platforms have been updated to support the new loading mechanism. + + The new mechanism is enabled by a build flag (`LOAD_IMAGE_V2`) which is + currently off by default for the AArch64 build. + + **Note** `TRUSTED_BOARD_BOOT` is currently not supported when `LOAD_IMAGE_V2` + is enabled. + +- Updated requirements for making contributions to TF-A. + + Commits now must have a 'Signed-off-by:' field to certify that the + contribution has been made under the terms of the + {download}`Developer Certificate of Origin <../dco.txt>`. + + A signed CLA is no longer required. + + The {ref}`Contributor's Guide` has been updated to reflect this change. + +- Introduced Performance Measurement Framework (PMF) which provides support for + capturing, storing, dumping and retrieving time-stamps to measure the + execution time of critical paths in the firmware. This relies on defining + fixed sample points at key places in the code. + +- To support the QEMU platform port, imported libfdt v1.4.1 from + + +- Updated PSCI support: + + - Added support for PSCI NODE_HW_STATE API for Arm platforms. + - New optional platform hook, `pwr_domain_pwr_down_wfi()`, in `plat_psci_ops` + to enable platforms to perform platform-specific actions needed to enter + powerdown, including the 'wfi' invocation. + - PSCI STAT residency and count functions have been added on Arm platforms by + using PMF. + +- Enhancements to the translation table library: + + - Limited memory mapping support for region overlaps to only allow regions to + overlap that are identity mapped or have the same virtual to physical + address offset, and overlap completely but must not cover the same area. + + This limitation will enable future enhancements without having to support + complex edge cases that may not be necessary. + + - The initial translation lookup level is now inferred from the virtual + address space size. Previously, it was hard-coded. + + - Added support for mapping Normal, Inner Non-cacheable, Outer Non-cacheable + memory in the translation table library. + + This can be useful to map a non-cacheable memory region, such as a DMA + buffer. + + - Introduced the MT_EXECUTE/MT_EXECUTE_NEVER memory mapping attributes to + specify the access permissions for instruction execution of a memory region. + +- Enabled support to isolate code and read-only data on separate memory pages, + allowing independent access control to be applied to each. + +- Enabled SCR_EL3.SIF (Secure Instruction Fetch) bit in BL1 and BL31 common + architectural setup code, preventing fetching instructions from non-secure + memory when in secure state. + +- Enhancements to FIP support: + + - Replaced `fip_create` with `fiptool` which provides a more consistent and + intuitive interface as well as additional support to remove an image from a + FIP file. + - Enabled printing the SHA256 digest with info command, allowing quick + verification of an image within a FIP without having to extract the image + and running sha256sum on it. + - Added support for unpacking the contents of an existing FIP file into the + working directory. + - Aligned command line options for specifying images to use same naming + convention as specified by TBBR and already used in cert_create tool. + +- Refactored the TZC-400 driver to also support memory controllers that + integrate TZC functionality, for example Arm CoreLink DMC-500. Also added + DMC-500 specific support. + +- Implemented generic delay timer based on the system generic counter and + migrated all platforms to use it. + +- Enhanced support for Arm platforms: + + - Updated image loading support to make SCP images (SCP_BL2 and SCP_BL2U) + optional. + - Enhanced topology description support to allow multi-cluster topology + definitions. + - Added interconnect abstraction layer to help platform ports select the right + interconnect driver, CCI or CCN, for the platform. + - Added support to allow loading BL31 in the TZC-secured DRAM instead of the + default secure SRAM. + - Added support to use a System Security Control (SSC) Registers Unit enabling + TF-A to be compiled to support multiple Arm platforms and then select one at + runtime. + - Restricted mapping of Trusted ROM in BL1 to what is actually needed by BL1 + rather than entire Trusted ROM region. + - Flash is now mapped as execute-never by default. This increases security by + restricting the executable region to what is strictly needed. + +- Applied following erratum workarounds for Cortex-A57: 833471, 826977, 829520, + 828024 and 826974. + +- Added support for Mediatek MT6795 platform. + +- Added support for QEMU virtualization Armv8-A target. + +- Added support for Rockchip RK3368 and RK3399 platforms. + +- Added support for Xilinx Zynq UltraScale+ MPSoC platform. + +- Added support for Arm Cortex-A73 MPCore Processor. + +- Added support for Arm Cortex-A72 processor. + +- Added support for Arm Cortex-A35 processor. + +- Added support for Arm Cortex-A32 MPCore Processor. + +- Enabled preloaded BL33 alternative boot flow, in which BL2 does not load BL33 + from non-volatile storage and BL31 hands execution over to a preloaded BL33. + The User Guide has been updated with an example of how to use this option with + a bootwrapped kernel. + +- Added support to build TF-A on a Windows-based host machine. + +- Updated Trusted Board Boot prototype implementation: + + - Enabled the ability for a production ROM with TBBR enabled to boot test + software before a real ROTPK is deployed (e.g. manufacturing mode). Added + support to use ROTPK in certificate without verifying against the platform + value when `ROTPK_NOT_DEPLOYED` bit is set. + - Added support for non-volatile counter authentication to the Authentication + Module to protect against roll-back. + +- Updated GICv3 support: + + - Enabled processor power-down and automatic power-on using GICv3. + - Enabled G1S or G0 interrupts to be configured independently. + - Changed FVP default interrupt driver to be the GICv3-only driver. **Note** + the default build of TF-A will not be able to boot Linux kernel with GICv2 + FDT blob. + - Enabled wake-up from CPU_SUSPEND to stand-by by temporarily re-routing + interrupts and then restoring after resume. + +### Issues resolved since last release + +### Known issues + +- The version of the AEMv8 Base FVP used in this release resets the model + instead of terminating its execution in response to a shutdown request using + the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of the + model. +- Building TF-A with compiler optimisations disabled (`-O0`) fails. +- TF-A cannot be built with mbed TLS version v2.3.0 due to build warnings that + the TF-A build system interprets as errors. +- TBBR is not currently supported when running TF-A in AArch32 state. + +## 1.2 (2015-12-22) + +### New features + +- The Trusted Board Boot implementation on Arm platforms now conforms to the + mandatory requirements of the TBBR specification. + + In particular, the boot process is now guarded by a Trusted Watchdog, which + will reset the system in case of an authentication or loading error. On Arm + platforms, a secure instance of Arm SP805 is used as the Trusted Watchdog. + + Also, a firmware update process has been implemented. It enables authenticated + firmware to update firmware images from external interfaces to SoC + Non-Volatile memories. This feature functions even when the current firmware + in the system is corrupt or missing; it therefore may be used as a recovery + mode. + +- Improvements have been made to the Certificate Generation Tool (`cert_create`) + as follows. + + - Added support for the Firmware Update process by extending the Chain of + Trust definition in the tool to include the Firmware Update certificate and + the required extensions. + - Introduced a new API that allows one to specify command line options in the + Chain of Trust description. This makes the declaration of the tool's + arguments more flexible and easier to extend. + - The tool has been reworked to follow a data driven approach, which makes it + easier to maintain and extend. + +- Extended the FIP tool (`fip_create`) to support the new set of images involved + in the Firmware Update process. + +- Various memory footprint improvements. In particular: + + - The bakery lock structure for coherent memory has been optimised. + - The mbed TLS SHA1 functions are not needed, as SHA256 is used to generate + the certificate signature. Therefore, they have been compiled out, reducing + the memory footprint of BL1 and BL2 by approximately 6 KB. + - On Arm development platforms, each BL stage now individually defines the + number of regions that it needs to map in the MMU. + +- Added the following new design documents: + + - {ref}`Authentication Framework & Chain of Trust` + - {ref}`Firmware Update (FWU)` + - {ref}`CPU Reset` + - {ref}`PSCI Power Domain Tree Structure` + +- Applied the new image terminology to the code base and documentation, as + described in the {ref}`Image Terminology` document. + +- The build system has been reworked to improve readability and facilitate + adding future extensions. + +- On Arm standard platforms, BL31 uses the boot console during cold boot but + switches to the runtime console for any later logs at runtime. The TSP uses + the runtime console for all output. + +- Implemented a basic NOR flash driver for Arm platforms. It programs the device + using CFI (Common Flash Interface) standard commands. + +- Implemented support for booting EL3 payloads on Arm platforms, which reduces + the complexity of developing EL3 baremetal code by doing essential baremetal + initialization. + +- Provided separate drivers for GICv3 and GICv2. These expect the entire + software stack to use either GICv2 or GICv3; hybrid GIC software systems are + no longer supported and the legacy Arm GIC driver has been deprecated. + +- Added support for Juno r1 and r2. A single set of Juno TF-A binaries can run + on Juno r0, r1 and r2 boards. Note that this TF-A version depends on a Linaro + release that does *not* contain Juno r2 support. + +- Added support for MediaTek mt8173 platform. + +- Implemented a generic driver for Arm CCN IP. + +- Major rework of the PSCI implementation. + + - Added framework to handle composite power states. + - Decoupled the notions of affinity instances (which describes the + hierarchical arrangement of cores) and of power domain topology, instead of + assuming a one-to-one mapping. + - Better alignment with version 1.0 of the PSCI specification. + +- Added support for the SYSTEM_SUSPEND PSCI API on Arm platforms. When invoked + on the last running core on a supported platform, this puts the system into a + low power mode with memory retention. + +- Unified the reset handling code as much as possible across BL stages. Also + introduced some build options to enable optimization of the reset path on + platforms that support it. + +- Added a simple delay timer API, as well as an SP804 timer driver, which is + enabled on FVP. + +- Added support for NVidia Tegra T210 and T132 SoCs. + +- Reorganised Arm platforms ports to greatly improve code shareability and + facilitate the reuse of some of this code by other platforms. + +- Added support for Arm Cortex-A72 processor in the CPU specific framework. + +- Provided better error handling. Platform ports can now define their own error + handling, for example to perform platform specific bookkeeping or post-error + actions. + +- Implemented a unified driver for Arm Cache Coherent Interconnects used for + both CCI-400 & CCI-500 IPs. Arm platforms ports have been migrated to this + common driver. The standalone CCI-400 driver has been deprecated. + +### Issues resolved since last release + +- The Trusted Board Boot implementation has been redesigned to provide greater + modularity and scalability. See the + \{ref}`Authentication Framework & Chain of Trust` document. All missing + mandatory features are now implemented. +- The FVP and Juno ports may now use the hash of the ROTPK stored in the Trusted + Key Storage registers to verify the ROTPK. Alternatively, a development public + key hash embedded in the BL1 and BL2 binaries might be used instead. The + location of the ROTPK is chosen at build-time using the `ARM_ROTPK_LOCATION` + build option. +- GICv3 is now fully supported and stable. + +### Known issues + +- The version of the AEMv8 Base FVP used in this release resets the model + instead of terminating its execution in response to a shutdown request using + the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of the + model. +- While this version has low on-chip RAM requirements, there are further RAM + usage enhancements that could be made. +- The upstream documentation could be improved for structural consistency, + clarity and completeness. In particular, the design documentation is + incomplete for PSCI, the TSP(D) and the Juno platform. +- Building TF-A with compiler optimisations disabled (`-O0`) fails. + +## 1.1 (2015-02-04) + +### New features + +- A prototype implementation of Trusted Board Boot has been added. Boot loader + images are verified by BL1 and BL2 during the cold boot path. BL1 and BL2 use + the PolarSSL SSL library to verify certificates and images. The OpenSSL + library is used to create the X.509 certificates. Support has been added to + `fip_create` tool to package the certificates in a FIP. + +- Support for calling CPU and platform specific reset handlers upon entry into + BL3-1 during the cold and warm boot paths has been added. This happens after + another Boot ROM `reset_handler()` has already run. This enables a developer + to perform additional actions or undo actions already performed during the + first call of the reset handlers e.g. apply additional errata workarounds. + +- Support has been added to demonstrate routing of IRQs to EL3 instead of S-EL1 + when execution is in secure world. + +- The PSCI implementation now conforms to version 1.0 of the PSCI specification. + All the mandatory APIs and selected optional APIs are supported. In + particular, support for the `PSCI_FEATURES` API has been added. A capability + variable is constructed during initialization by examining the `plat_pm_ops` + and `spd_pm_ops` exported by the platform and the Secure Payload Dispatcher. + This is used by the PSCI FEATURES function to determine which PSCI APIs are + supported by the platform. + +- Improvements have been made to the PSCI code as follows. + + - The code has been refactored to remove redundant parameters from internal + functions. + - Changes have been made to the code for PSCI `CPU_SUSPEND`, `CPU_ON` and + `CPU_OFF` calls to facilitate an early return to the caller in case a + failure condition is detected. For example, a PSCI `CPU_SUSPEND` call + returns `SUCCESS` to the caller if a pending interrupt is detected early in + the code path. + - Optional platform APIs have been added to validate the `power_state` and + `entrypoint` parameters early in PSCI `CPU_ON` and `CPU_SUSPEND` code paths. + - PSCI migrate APIs have been reworked to invoke the SPD hook to determine the + type of Trusted OS and the CPU it is resident on (if applicable). Also, + during a PSCI `MIGRATE` call, the SPD hook to migrate the Trusted OS is + invoked. + +- It is now possible to build TF-A without marking at least an extra page of + memory as coherent. The build flag `USE_COHERENT_MEM` can be used to choose + between the two implementations. This has been made possible through these + changes. + + - An implementation of Bakery locks, where the locks are not allocated in + coherent memory has been added. + - Memory which was previously marked as coherent is now kept coherent through + the use of software cache maintenance operations. + + Approximately, 4K worth of memory is saved for each boot loader stage when + `USE_COHERENT_MEM=0`. Enabling this option increases the latencies associated + with acquire and release of locks. It also requires changes to the platform + ports. + +- It is now possible to specify the name of the FIP at build time by defining + the `FIP_NAME` variable. + +- Issues with dependencies on the 'fiptool' makefile target have been rectified. + The `fip_create` tool is now rebuilt whenever its source files change. + +- The BL3-1 runtime console is now also used as the crash console. The crash + console is changed to SoC UART0 (UART2) from the previous FPGA UART0 (UART0) + on Juno. In FVP, it is changed from UART0 to UART1. + +- CPU errata workarounds are applied only when the revision and part number + match. This behaviour has been made consistent across the debug and release + builds. The debug build additionally prints a warning if a mismatch is + detected. + +- It is now possible to issue cache maintenance operations by set/way for a + particular level of data cache. Levels 1-3 are currently supported. + +- The following improvements have been made to the FVP port. + + - The build option `FVP_SHARED_DATA_LOCATION` which allowed relocation of + shared data into the Trusted DRAM has been deprecated. Shared data is now + always located at the base of Trusted SRAM. + - BL2 Translation tables have been updated to map only the region of DRAM + which is accessible to normal world. This is the region of the 2GB DDR-DRAM + memory at 0x80000000 excluding the top 16MB. The top 16MB is accessible to + only the secure world. + - BL3-2 can now reside in the top 16MB of DRAM which is accessible only to the + secure world. This can be done by setting the build flag + `FVP_TSP_RAM_LOCATION` to the value `dram`. + +- Separate translation tables are created for each boot loader image. The + `IMAGE_BLx` build options are used to do this. This allows each stage to + create mappings only for areas in the memory map that it needs. + +- A Secure Payload Dispatcher (OPTEED) for the OP-TEE Trusted OS has been added. + Details of using it with TF-A can be found in {ref}`OP-TEE Dispatcher` + +### Issues resolved since last release + +- The Juno port has been aligned with the FVP port as follows. + + - Support for reclaiming all BL1 RW memory and BL2 memory by overlaying the + BL3-1/BL3-2 NOBITS sections on top of them has been added to the Juno port. + - The top 16MB of the 2GB DDR-DRAM memory at 0x80000000 is configured using + the TZC-400 controller to be accessible only to the secure world. + - The Arm GIC driver is used to configure the GIC-400 instead of using a GIC + driver private to the Juno port. + - PSCI `CPU_SUSPEND` calls that target a standby state are now supported. + - The TZC-400 driver is used to configure the controller instead of direct + accesses to the registers. + +- The Linux kernel version referred to in the user guide has DVFS and HMP + support enabled. + +- DS-5 v5.19 did not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in CADI + server mode. This issue is not seen with DS-5 v5.20 and Version 6.2 of the + Cortex-A57-A53 Base FVPs. + +### Known issues + +- The Trusted Board Boot implementation is a prototype. There are issues with + the modularity and scalability of the design. Support for a Trusted Watchdog, + firmware update mechanism, recovery images and Trusted debug is absent. These + issues will be addressed in future releases. +- The FVP and Juno ports do not use the hash of the ROTPK stored in the Trusted + Key Storage registers to verify the ROTPK in the `plat_match_rotpk()` + function. This prevents the correct establishment of the Chain of Trust at the + first step in the Trusted Board Boot process. +- The version of the AEMv8 Base FVP used in this release resets the model + instead of terminating its execution in response to a shutdown request using + the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of the + model. +- GICv3 support is experimental. There are known issues with GICv3 + initialization in the TF-A. +- While this version greatly reduces the on-chip RAM requirements, there are + further RAM usage enhancements that could be made. +- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. +- The Juno-specific firmware design documentation is incomplete. + +## 1.0 (2014-08-28) + +### New features + +- It is now possible to map higher physical addresses using non-flat virtual to + physical address mappings in the MMU setup. + +- Wider use is now made of the per-CPU data cache in BL3-1 to store: + + - Pointers to the non-secure and secure security state contexts. + - A pointer to the CPU-specific operations. + - A pointer to PSCI specific information (for example the current power + state). + - A crash reporting buffer. + +- The following RAM usage improvements result in a BL3-1 RAM usage reduction + from 96KB to 56KB (for FVP with TSPD), and a total RAM usage reduction across + all images from 208KB to 88KB, compared to the previous release. + + - Removed the separate `early_exception` vectors from BL3-1 (2KB code size + saving). + - Removed NSRAM from the FVP memory map, allowing the removal of one (4KB) + translation table. + - Eliminated the internal `psci_suspend_context` array, saving 2KB. + - Correctly dimensioned the PSCI `aff_map_node` array, saving 1.5KB in the FVP + port. + - Removed calling CPU mpidr from the bakery lock API, saving 160 bytes. + - Removed current CPU mpidr from PSCI common code, saving 160 bytes. + - Inlined the mmio accessor functions, saving 360 bytes. + - Fully reclaimed all BL1 RW memory and BL2 memory on the FVP port by + overlaying the BL3-1/BL3-2 NOBITS sections on top of these at runtime. + - Made storing the FP register context optional, saving 0.5KB per context (8KB + on the FVP port, with TSPD enabled and running on 8 CPUs). + - Implemented a leaner `tf_printf()` function, allowing the stack to be + greatly reduced. + - Removed coherent stacks from the codebase. Stacks allocated in normal memory + are now used before and after the MMU is enabled. This saves 768 bytes per + CPU in BL3-1. + - Reworked the crash reporting in BL3-1 to use less stack. + - Optimized the EL3 register state stored in the `cpu_context` structure so + that registers that do not change during normal execution are re-initialized + each time during cold/warm boot, rather than restored from memory. This + saves about 1.2KB. + - As a result of some of the above, reduced the runtime stack size in all BL + images. For BL3-1, this saves 1KB per CPU. + +- PSCI SMC handler improvements to correctly handle calls from secure states and + from AArch32. + +- CPU contexts are now initialized from the `entry_point_info`. BL3-1 fully + determines the exception level to use for the non-trusted firmware (BL3-3) + based on the SPSR value provided by the BL2 platform code (or otherwise + provided to BL3-1). This allows platform code to directly run non-trusted + firmware payloads at either EL2 or EL1 without requiring an EL2 stub or OS + loader. + +- Code refactoring improvements: + + - Refactored `fvp_config` into a common platform header. + - Refactored the fvp gic code to be a generic driver that no longer has an + explicit dependency on platform code. + - Refactored the CCI-400 driver to not have dependency on platform code. + - Simplified the IO driver so it's no longer necessary to call `io_init()` and + moved all the IO storage framework code to one place. + - Simplified the interface the the TZC-400 driver. + - Clarified the platform porting interface to the TSP. + - Reworked the TSPD setup code to support the alternate BL3-2 initialization + flow where BL3-1 generic code hands control to BL3-2, rather than expecting + the TSPD to hand control directly to BL3-2. + - Considerable rework to PSCI generic code to support CPU specific operations. + +- Improved console log output, by: + + - Adding the concept of debug log levels. + - Rationalizing the existing debug messages and adding new ones. + - Printing out the version of each BL stage at runtime. + - Adding support for printing console output from assembler code, including + when a crash occurs before the C runtime is initialized. + +- Moved up to the latest versions of the FVPs, toolchain, EDK2, kernel, Linaro + file system and DS-5. + +- On the FVP port, made the use of the Trusted DRAM region optional at build + time (off by default). Normal platforms will not have such a "ready-to-use" + DRAM area so it is not a good example to use it. + +- Added support for PSCI `SYSTEM_OFF` and `SYSTEM_RESET` APIs. + +- Added support for CPU specific reset sequences, power down sequences and + register dumping during crash reporting. The CPU specific reset sequences + include support for errata workarounds. + +- Merged the Juno port into the master branch. Added support for CPU hotplug and + CPU idle. Updated the user guide to describe how to build and run on the Juno + platform. + +### Issues resolved since last release + +- Removed the concept of top/bottom image loading. The image loader now + automatically detects the position of the image inside the current memory + layout and updates the layout to minimize fragmentation. This resolves the + image loader limitations of previously releases. There are currently no plans + to support dynamic image loading. +- CPU idle now works on the publicized version of the Foundation FVP. +- All known issues relating to the compiler version used have now been resolved. + This TF-A version uses Linaro toolchain 14.07 (based on GCC 4.9). + +### Known issues + +- GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in the + TF-A. + +- While this version greatly reduces the on-chip RAM requirements, there are + further RAM usage enhancements that could be made. + +- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. + +- The Juno-specific firmware design documentation is incomplete. + +- Some recent enhancements to the FVP port have not yet been translated into the + Juno port. These will be tracked via the tf-issues project. + +- The Linux kernel version referred to in the user guide has DVFS and HMP + support disabled due to some known instabilities at the time of this release. + A future kernel version will re-enable these features. + +- DS-5 v5.19 does not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in CADI + server mode. This is because the `` reported by the FVP in this + version has changed. For example, for the Cortex-A57x4-A53x4 Base FVP, the + `` reported by the FVP is `FVP_Base_Cortex_A57x4_A53x4`, while DS-5 + expects it to be `FVP_Base_A57x4_A53x4`. + + The temporary fix to this problem is to change the name of the FVP in + `sw/debugger/configdb/Boards/ARM FVP/Base_A57x4_A53x4/cadi_config.xml`. Change + the following line: + + ``` + System Generator:FVP_Base_A57x4_A53x4 + ``` + + to System Generator:FVP_Base_Cortex-A57x4_A53x4 + + A similar change can be made to the other Cortex-A57-A53 Base FVP variants. + +## 0.4 (2014-06-03) + +### New features + +- Makefile improvements: + + - Improved dependency checking when building. + - Removed `dump` target (build now always produces dump files). + - Enabled platform ports to optionally make use of parts of the Trusted + Firmware (e.g. BL3-1 only), rather than being forced to use all parts. Also + made the `fip` target optional. + - Specified the full path to source files and removed use of the `vpath` + keyword. + +- Provided translation table library code for potential re-use by platforms + other than the FVPs. + +- Moved architectural timer setup to platform-specific code. + +- Added standby state support to PSCI cpu_suspend implementation. + +- SRAM usage improvements: + + - Started using the `-ffunction-sections`, `-fdata-sections` and + `--gc-sections` compiler/linker options to remove unused code and data from + the images. Previously, all common functions were being built into all + binary images, whether or not they were actually used. + - Placed all assembler functions in their own section to allow more unused + functions to be removed from images. + - Updated BL1 and BL2 to use a single coherent stack each, rather than one per + CPU. + - Changed variables that were unnecessarily declared and initialized as + non-const (i.e. in the .data section) so they are either uninitialized (zero + init) or const. + +- Moved the Test Secure-EL1 Payload (BL3-2) to execute in Trusted SRAM by + default. The option for it to run in Trusted DRAM remains. + +- Implemented a TrustZone Address Space Controller (TZC-400) driver. A default + configuration is provided for the Base FVPs. This means the model parameter + `-C bp.secure_memory=1` is now supported. + +- Started saving the PSCI cpu_suspend 'power_state' parameter prior to + suspending a CPU. This allows platforms that implement multiple power-down + states at the same affinity level to identify a specific state. + +- Refactored the entire codebase to reduce the amount of nesting in header files + and to make the use of system/user includes more consistent. Also split + platform.h to separate out the platform porting declarations from the required + platform porting definitions and the definitions/declarations specific to the + platform port. + +- Optimized the data cache clean/invalidate operations. + +- Improved the BL3-1 unhandled exception handling and reporting. Unhandled + exceptions now result in a dump of registers to the console. + +- Major rework to the handover interface between BL stages, in particular the + interface to BL3-1. The interface now conforms to a specification and is more + future proof. + +- Added support for optionally making the BL3-1 entrypoint a reset handler + (instead of BL1). This allows platforms with an alternative image loading + architecture to re-use BL3-1 with fewer modifications to generic code. + +- Reserved some DDR DRAM for secure use on FVP platforms to avoid future + compatibility problems with non-secure software. + +- Added support for secure interrupts targeting the Secure-EL1 Payload (SP) + (using GICv2 routing only). Demonstrated this working by adding an interrupt + target and supporting test code to the TSP. Also demonstrated non-secure + interrupt handling during TSP processing. + +### Issues resolved since last release + +- Now support use of the model parameter `-C bp.secure_memory=1` in the Base + FVPs (see **New features**). +- Support for secure world interrupt handling now available (see **New + features**). +- Made enough SRAM savings (see **New features**) to enable the Test Secure-EL1 + Payload (BL3-2) to execute in Trusted SRAM by default. +- The tested filesystem used for this release (Linaro AArch64 OpenEmbedded + 14.04) now correctly reports progress in the console. +- Improved the Makefile structure to make it easier to separate out parts of the + TF-A for re-use in platform ports. Also, improved target dependency checking. + +### Known issues + +- GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in the + TF-A. +- Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead to + loading errors, even if the images should theoretically fit in memory. +- TF-A still uses too much on-chip Trusted SRAM. A number of RAM usage + enhancements have been identified to rectify this situation. +- CPU idle does not work on the advertised version of the Foundation FVP. Some + FVP fixes are required that are not available externally at the time of + writing. This can be worked around by disabling CPU idle in the Linux kernel. +- Various bugs in TF-A, UEFI and the Linux kernel have been observed when using + Linaro toolchain versions later than 13.11. Although most of these have been + fixed, some remain at the time of writing. These mainly seem to relate to a + subtle change in the way the compiler converts between 64-bit and 32-bit + values (e.g. during casting operations), which reveals previously hidden bugs + in client code. +- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. + +## 0.3 (2014-02-28) + +### New features + +- Support for Foundation FVP Version 2.0 added. The documented UEFI + configuration disables some devices that are unavailable in the Foundation + FVP, including MMC and CLCD. The resultant UEFI binary can be used on the + AEMv8 and Cortex-A57-A53 Base FVPs, as well as the Foundation FVP. + + \:::\{note} The software will not work on Version 1.0 of the Foundation FVP. + \::: + +- Enabled third party contributions. Added a new contributing.md containing + instructions for how to contribute and updated copyright text in all files to + acknowledge contributors. + +- The PSCI CPU_SUSPEND API has been stabilised to the extent where it can be + used for entry into power down states with the following restrictions: + + - Entry into standby states is not supported. + - The API is only supported on the AEMv8 and Cortex-A57-A53 Base FVPs. + +- The PSCI AFFINITY_INFO api has undergone limited testing on the Base FVPs to + allow experimental use. + +- Required C library and runtime header files are now included locally in TF-A + instead of depending on the toolchain standard include paths. The local + implementation has been cleaned up and reduced in scope. + +- Added I/O abstraction framework, primarily to allow generic code to load + images in a platform-independent way. The existing image loading code has been + reworked to use the new framework. Semi-hosting and NOR flash I/O drivers are + provided. + +- Introduced Firmware Image Package (FIP) handling code and tools. A FIP + combines multiple firmware images with a Table of Contents (ToC) into a single + binary image. The new FIP driver is another type of I/O driver. The Makefile + builds a FIP by default and the FVP platform code expect to load a FIP from + NOR flash, although some support for image loading using semi- hosting is + retained. + + \:::\{note} Building a FIP by default is a non-backwards-compatible change. ::: + + \:::\{note} Generic BL2 code now loads a BL3-3 (non-trusted firmware) image + into DRAM instead of expecting this to be pre-loaded at known location. This + is also a non-backwards-compatible change. ::: + + \:::\{note} Some non-trusted firmware (e.g. UEFI) will need to be rebuilt so + that it knows the new location to execute from and no longer needs to copy + particular code modules to DRAM itself. ::: + +- Reworked BL2 to BL3-1 handover interface. A new composite structure + (bl31_args) holds the superset of information that needs to be passed from BL2 + to BL3-1, including information on how handover execution control to BL3-2 (if + present) and BL3-3 (non-trusted firmware). + +- Added library support for CPU context management, allowing the saving and + restoring of + + - Shared system registers between Secure-EL1 and EL1. + - VFP registers. + - Essential EL3 system registers. + +- Added a framework for implementing EL3 runtime services. Reworked the PSCI + implementation to be one such runtime service. + +- Reworked the exception handling logic, making use of both SP_EL0 and SP_EL3 + stack pointers for determining the type of exception, managing general purpose + and system register context on exception entry/exit, and handling SMCs. SMCs + are directed to the correct EL3 runtime service. + +- Added support for a Test Secure-EL1 Payload (TSP) and a corresponding + Dispatcher (TSPD), which is loaded as an EL3 runtime service. The TSPD + implements Secure Monitor functionality such as world switching and EL1 + context management, and is responsible for communication with the TSP. + + \:::\{note} The TSPD does not yet contain support for secure world interrupts. + \::: + + \:::\{note} The TSP/TSPD is not built by default. ::: + +### Issues resolved since last release + +- Support has been added for switching context between secure and normal worlds + in EL3. +- PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` have now been tested (to a + limited extent). +- The TF-A build artifacts are now placed in the `./build` directory and + sub-directories instead of being placed in the root of the project. +- TF-A is now free from build warnings. Build warnings are now treated as + errors. +- TF-A now provides C library support locally within the project to maintain + compatibility between toolchains/systems. +- The PSCI locking code has been reworked so it no longer takes locks in an + incorrect sequence. +- The RAM-disk method of loading a Linux file-system has been confirmed to work + with the TF-A and Linux kernel version (based on version 3.13) used in this + release, for both Foundation and Base FVPs. + +### Known issues + +The following is a list of issues which are expected to be fixed in the future +releases of TF-A. + +- The TrustZone Address Space Controller (TZC-400) is not being programmed yet. + Use of model parameter `-C bp.secure_memory=1` is not supported. +- No support yet for secure world interrupt handling. +- GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in + TF-A. +- Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead to + loading errors, even if the images should theoretically fit in memory. +- TF-A uses too much on-chip Trusted SRAM. Currently the Test Secure-EL1 Payload + (BL3-2) executes in Trusted DRAM since there is not enough SRAM. A number of + RAM usage enhancements have been identified to rectify this situation. +- CPU idle does not work on the advertised version of the Foundation FVP. Some + FVP fixes are required that are not available externally at the time of + writing. +- Various bugs in TF-A, UEFI and the Linux kernel have been observed when using + Linaro toolchain versions later than 13.11. Although most of these have been + fixed, some remain at the time of writing. These mainly seem to relate to a + subtle change in the way the compiler converts between 64-bit and 32-bit + values (e.g. during casting operations), which reveals previously hidden bugs + in client code. +- The tested filesystem used for this release (Linaro AArch64 OpenEmbedded + 14.01) does not report progress correctly in the console. It only seems to + produce error output, not standard output. It otherwise appears to function + correctly. Other filesystem versions on the same software stack do not exhibit + the problem. +- The Makefile structure doesn't make it easy to separate out parts of the TF-A + for re-use in platform ports, for example if only BL3-1 is required in a + platform port. Also, dependency checking in the Makefile is flawed. +- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and + its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. + +## 0.2 (2013-10-25) + +### New features + +- First source release. +- Code for the PSCI suspend feature is supplied, although this is not enabled by + default since there are known issues (see below). + +### Issues resolved since last release + +- The "psci" nodes in the FDTs provided in this release now fully comply with + the recommendations made in the PSCI specification. + +### Known issues + +The following is a list of issues which are expected to be fixed in the future +releases of TF-A. + +- The TrustZone Address Space Controller (TZC-400) is not being programmed yet. + Use of model parameter `-C bp.secure_memory=1` is not supported. +- No support yet for secure world interrupt handling or for switching context + between secure and normal worlds in EL3. +- GICv3 support is experimental. The Linux kernel patches to support this are + not widely available. There are known issues with GICv3 initialization in + TF-A. +- Dynamic image loading is not available yet. The current image loader + implementation (used to load BL2 and all subsequent images) has some + limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead to + loading errors, even if the images should theoretically fit in memory. +- Although support for PSCI `CPU_SUSPEND` is present, it is not yet stable and + ready for use. +- PSCI API calls `AFFINITY_INFO` & `PSCI_VERSION` are implemented but have not + been tested. +- The TF-A make files result in all build artifacts being placed in the root of + the project. These should be placed in appropriate sub-directories. +- The compilation of TF-A is not free from compilation warnings. Some of these + warnings have not been investigated yet so they could mask real bugs. +- TF-A currently uses toolchain/system include files like stdio.h. It should + provide versions of these within the project to maintain compatibility between + toolchains/systems. +- The PSCI code takes some locks in an incorrect sequence. This may cause + problems with suspend and hotplug in certain conditions. +- The Linux kernel used in this release is based on version 3.12-rc4. Using this + kernel with the TF-A fails to start the file-system as a RAM-disk. It fails to + execute user-space `init` from the RAM-disk. As an alternative, the + VirtioBlock mechanism can be used to provide a file-system to the kernel. + +______________________________________________________________________ + +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* + +[mbed tls releases]: https://tls.mbed.org/tech-updates/releases +[pr#1002]: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193 +[sdei specification]: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf +[tf-issue#501]: https://github.com/ARM-software/tf-issues/issues/501 diff --git a/docs/change-log.rst b/docs/change-log.rst deleted file mode 100644 index 9c475689a..000000000 --- a/docs/change-log.rst +++ /dev/null @@ -1,4602 +0,0 @@ -Change Log & Release Notes -========================== - -This document contains a summary of the new features, changes, fixes and known -issues in each release of Trusted Firmware-A. - -Version 2.5 ------------ - -New Features -^^^^^^^^^^^^ - -- Architecture support - - Added support for speculation barrier(``FEAT_SB``) for non-Armv8.5 - platforms starting from Armv8.0 - - Added support for Activity Monitors Extension version 1.1(``FEAT_AMUv1p1``) - - Added helper functions for Random number generator(``FEAT_RNG``) registers - - Added support for Armv8.6 Multi-threaded PMU extensions (``FEAT_MTPMU``) - - Added support for MTE Asymmetric Fault Handling extensions(``FEAT_MTE3``) - - Added support for Privileged Access Never extensions(``FEAT_PANx``) - -- Bootloader images - - Added PIE support for AArch32 builds - - Enable Trusted Random Number Generator service for BL32(sp_min) - -- Build System - - Added build option for Arm Feature Modifiers - -- Drivers - - Added support for interrupts in TZC-400 driver - - - Broadcom - - Added support for I2C, MDIO and USB drivers - - - Marvell - - Added support for secure read/write of dfc register-set - - Added support for thermal sensor driver - - Implement a3700_core_getc API in console driver - - Added rx training on 10G port - - - Marvell Mochi - - Added support for cn913x in PCIe mode - - - Marvell Armada A8K - - Added support for TRNG-IP-76 driver and accessing RNG register - - - Mediatek MT8192 - - Added support for following drivers - - MPU configuration for SCP/PCIe - - SPM suspend - - Vcore DVFS - - LPM - - PTP3 - - UART save and restore - - Power-off - - PMIC - - CPU hotplug and MCDI support - - SPMC - - MPU - - - Mediatek MT8195 - - Added support for following drivers - - GPIO, NCDI, SPMC drivers - - Power-off - - CPU hotplug, reboot and MCDI - - Delay timer and sys timer - - GIC - - - NXP - - Added support for - - non-volatile storage API - - chain of trust and trusted board boot using two modes: MBEDTLS and CSF - - fip-handler necessary for DDR initialization - - SMMU and console drivers - - crypto hardware accelerator driver - - following drivers: SD, EMMC, QSPI, FLEXSPI, GPIO, GIC, CSU, PMU, DDR - - NXP Security Monitor and SFP driver - - interconnect config APIs using ARM CCN-CCI driver - - TZC APIs to configure DDR region - - generic timer driver - - Device configuration driver - - - IMX - - Added support for image loading and io-storage driver for TBBR fip booting - - - Renesas - - Added support for PFC and EMMC driver - - - RZ Family: - - G2N, G2E and G2H SoCs - - Added support for watchdog, QoS, PFC and DRAM initialization - - - RZG Family: - - G2M - - Added support for QoS and DRAM initialization - - - Xilinx - - Added JTAG DCC support for Versal and ZynqMP SoC family. - -- Libraries - - C standard library - - Added support to print ``%`` in ``snprintf()`` and ``printf()`` APIs - - Added support for strtoull, strtoll, strtoul, strtol APIs from FreeBSD project - - - CPU support - - Added support for - - Cortex_A78C CPU - - Makalu ELP CPU - - Makalu CPU - - Matterhorn ELP CPU - - Neoverse-N2 CPU - - - CPU Errata - - Arm Cortex-A76: Added workaround for erratum 1946160 - - - Arm Cortex-A77: Added workaround for erratum 1946167 - - - Arm Cortex-A78: Added workaround for erratum 1941498 and 1951500 - - - Arm Neoverse-N1: Added workaround for erratum 1946160 - - - Flattened device tree(libfdt) - - Added support for wrapper function to read UUIDs in string format from dtb - -- Platforms - - Added support for MediaTek MT8195 - - Added support for Arm RD-N2 board - - - Allwinner - - Added support for H616 SoC - - - Arm - - Added support for GPT parser - - Protect GICR frames for fused/unused cores - - - Arm Morello - - Added VirtIO network device to Morello FVP fdts - - - Arm RD-N2 - - Added support for variant 1 of RD-N2 platform - - Enable AMU support - - - Arm RD-V1 - - Enable AMU support - - - Arm SGI - - Added support for platform variant build option - - - Arm TC0 - - Added Matterhorn ELP CPU support - - Added support for opteed - - - Arm Juno - - Added support to use hw_config in BL31 - - Use TRNG entropy source for SMCCC TRNG interface - - Condition Juno entropy source with CRC instructions - - - Marvell Mochi - - Added support for detection of secure mode - - - Marvell ARMADA - - Added support for new compile option A3720_DB_PM_WAKEUP_SRC - - Added support doing system reset via CM3 secure coprocessor - - Made several makefile enhancements required to build WTMI_MULTI_IMG and TIMDDRTOOL - - Added support for building DOIMAGETOOL tool - - Added new target mrvl_bootimage - - - Mediatek MT8192 - - Added support for rtc power off sequence - - - Mediatek MT8195 - - Added support for SiP service - - - STM32MP1 - - Added support for - - Seeed ODYSSEY SoM and board - - SDMMC2 and I2C2 pins in pinctrl - - I2C2 peripheral in DTS - - PIE for BL32 - - TZC-400 interrupt managament - - Linux Automation MC-1 board - - - Renesas RZG - - Added support for identifying EK874 RZ/G2E board - - Added support for identifying HopeRun HiHope RZ/G2H and RZ/G2H boards - - - Rockchip - - Added support for stack protector - - - QEMU - - Added support for ``max`` CPU - - Added Cortex-A72 support to ``virt`` platform - - Enabled trigger reboot from secure pl061 - - - QEMU SBSA - - Added support for sbsa-ref Embedded Controller - - - NXP - - Added support for warm reset to retain ddr content - - Added support for image loader necessary for loading fip image - - - lx2160a SoC Family - - Added support for - - new platform lx2160a-aqds - - new platform lx2160a-rdb - - new platform lx2162a-aqds - - errata handling - - - IMX imx8mm - - Added support for trusted board boot - - - TI K3 - - Added support for lite device board - - Enabled Cortex-A72 erratum 1319367 - - Enabled Cortex-A53 erratum 1530924 - - - Xilinx ZynqMP - - Added support for PS and system reset on WDT restart - - Added support for error management - - Enable support for log messages necessary for debug - - Added support for PM API SMC call for efuse and register access - -- Processes - - Introduced process for platform deprecation - - Added documentation for TF-A threat model - - Provided a copy of the MIT license to comply with the license - requirements of the arm-gic.h source file (originating from the Linux - kernel project and re-distributed in TF-A). - -- Services - - Added support for TRNG firmware interface service - - - Arm - - Added SiP service to configure Ethos-N NPU - - - SPMC - - Added documentation for SPM(Hafnium) SMMUv3 driver - - - SPMD - - Added support for - - FFA_INTERRUPT forwading ABI - - FFA_SECONDARY_EP_REGISTER ABI - - FF-A v1.0 boot time power management, SPMC secondary core boot and - early run-time power management - -- Tools - - - FIPTool - - Added mechanism to allow platform specific image UUID - - - git hooks - - Added support for conventional commits through commitlint hook, - commitizen hook and husky configuration files. - - - NXP tool - - Added support for a tool that creates pbl file from BL2 - - - Renesas RZ/G2 - - Added tool support for creating bootparam and cert_header images - - - CertCreate - - Added support for platform-defined certificates, keys, and extensions using - the platform's makefile - - - shared tools - - Added EFI_GUID representation to uuid helper data structure - -Changed -^^^^^^^ - -- Common components - - Print newline after hex address in aarch64 el3_panic function - - Use proper ``#address-cells`` and ``#size-cells`` for reserved-memory in dtbs - -- Drivers - - - Move SCMI driver from ST platform directory and make it common to all platforms - - - Arm GICv3 - - Shift eSPI register offset in GICD_OFFSET_64() - - Use mpidr to probe GICR for current CPU - - - Arm TZC-400 - - Adjust filter tag if it set to FILTER_BIT_ALL - - - Cadence - - Enhance UART driver APIs to put characters to fifo - - - Mediatek MT8192 - - Move timer driver to common folder - - Enhanced sys_cirq driver to add more IC services - - - Renesas - - Move ddr and delay driver to common directory - - - Renesas rcar - - Treat log as device memory in console driver - - - Renesas RZ Family: - - G2N and G2H SoCs - - Select MMC_CH1 for eMMC channel - - - Marvell - - Added support for checking if TRNG unit is present - - - Marvell A3K - - Set TXDCLK_2X_SEL bit during PCIe initialization - - Set mask parameter for every reg_set call - - - Marvell Mochi - - Added missing stream IDs configurations - - - MbedTLS - - Migrated to Mbed TLS v2.26.0 - - - IMX imx8mp - - Change the bl31 physical load address - - - QEMU SBSA - - Enable secure variable storage - - - SCMI - - Update power domain protocol version to 2.0 - - - STM32 - - Remove dead code from nand FMC driver - -- Libraries - - C Standard Library - - Use macros to reduce duplicated code between snprintf and printf - - - CPU support - - Sanity check pointers before use in AArch32 builds - - - Arm Cortex-A78 - - Remove rainier cpu workaround for errata 1542319 - - - Arm Makalu ELP - - Added "_arm" suffix to Makalu ELP CPU lib - - -- Miscellaneous - - Editorconfig - - set max line length to 100 - -- Platforms - - Allwinner - - Added reserved-memory node to DT - - Express memmap more dynamically - - Move SEPARATE_NOBITS_REGION to platforms - - Limit FDT checks to reduce code size - - Use CPUIDLE hardware when available - - Allow conditional compilation of SCPI and native PSCI ops - - Always use a 3MHz RSB bus clock - - Enable workaround for Cortex-A53 erratum 1530924 - - Fixed non-default PRELOADED_BL33_BASE - - Leave CPU power alone during BL31 setup - - Added several psci hooks enhancements to improve system shutdown/reset - sequence - - Return the PMIC to I2C mode after use - - Separate code to power off self and other CPUs - - Split native and SCPI-based PSCI implementations - - - Allwinner H6 - - Added R_PRCM security setup for H6 board - - Added SPC security setup for H6 board - - Use RSB for the PMIC connection on H6 - - - Arm - - Store UUID as a string, rather than ints - - Replace FIP base and size macro with a generic name - - Move compile time switch from source to dt file - - Don't provide NT_FW_CONFIG when booting hafnium - - Do not setup 'disabled' regulator - - Increase SP max size - - Remove false dependency of ARM_LINUX_KERNEL_AS_BL33 on RESET_TO_BL31 - and allow it to be enabled independently - - - Arm FVP - - Do not map GIC region in BL1 and BL2 - - - Arm Juno - - Refactor juno_getentropy() to return 64 bits on each call - - - Arm Morello - - Remove "virtio-rng" from Morello FVP - - Enable virtIO P9 device for Morello fvp - - - Arm RDV1 - - Allow all PSCI callbacks on RD-V1 - - Rename rddaniel to rdv1 - - - Arm RDV1MC - - Rename rddanielxlr to rdv1mc - - Initialize TZC-400 controllers - - - Arm TC0 - - Updated GICR base address - - Use scmi_dvfs clock index 1 for cores 4-7 through fdt - - Added reserved-memory node for OP-TEE fdts - - Enabled Theodul DSU in TC platform - - OP-TEE as S-EL1 SP with SPMC at S-EL2 - - Update Matterhorm ELP DVFS clock index - - - Arm SGI - - Allow access to TZC controller on all chips - - Define memory regions for multi-chip platforms - - Allow access to nor2 flash and system registers from S-EL0 - - Define default list of memory regions for DMC-620 TZC - - Improve macros defining cper buffer memory region - - Refactor DMC-620 error handling SMC function id - - Refactor SDEI specific macros - - Added platform id value for RDN2 platform - - Refactored header file inclusions and inclusion of memory mapping - - - Arm RDN2 - - Allow usage of secure partitions on RDN2 platform - - Update GIC redistributor and TZC base address - - - Arm SGM775 - - Deprecate Arm sgm775 FVP platform - - - Marvell - - Increase TX FIFO EMPTY timeout from 2ms to 3ms - - Update delay code to be compatible with 1200 MHz CPU - - - Marvell ARMADA - - Postpone MSS CPU startup to BL31 stage - - Allow builds without MSS support - - Use MSS SRAM in secure mode - - Added missing FORCE, .PHONY and clean targets - - Cleanup MSS SRAM if used for copy - - Move definition of mrvl_flash target to common marvell_common.mk file - - Show informative build messages and blank lines - - - Marvell ARMADA A3K - - Added a new target mrvl_uart which builds UART image - - Added checks that WTP, MV_DDR_PATH and CRYPTOPP_PATH are correctly defined - - Allow use of the system Crypto++ library - - Build $(WTMI_ENC_IMG) in $(BUILD_PLAT) directory - - Build intermediate files in $(BUILD_PLAT) directory - - Build UART image files directly in $(BUILD_UART) subdirectory - - Correctly set DDR_TOPOLOGY and CLOCKSPRESET for WTMI - - Do not use 'echo -e' in Makefile - - Improve 4GB DRAM usage from 3.375 GB to 3.75 GB - - Remove unused variable WTMI_SYSINIT_IMG from Makefile - - Simplify check if WTP variable is defined - - Split building $(WTMI_MULTI_IMG) and $(TIMDDRTOOL) - - - Marvell ARMADA A8K - - Allow CP1/CP2 mapping at BLE stage - - - Mediatek MT8183 - - Added timer V20 compensation - - - Nvidia Tegra - - Rename SMC API - - - TI K3 - - Make plat_get_syscnt_freq2 helper check CNT_FID0 register - - Fill non-message data fields in sec_proxy with 0x0 - - Update ti_sci_msg_req_reboot ABI to include domain - - Enable USE_COHERENT_MEM only for the generic board - - Explicitly map SEC_SRAM_BASE to 0x0 - - Use BL31_SIZE instead of computing - - Define the correct number of max table entries and increase SRAM size - to account for additional table - - - Raspberry Pi4 - - Switch to gicv2.mk and GICV2_SOURCES - - - Renesas - - Move headers and assembly files to common folder - - - Renesas rzg - - Added device tree memory node enhancements - - - Rockchip - - Switch to using common gicv3.mk - - - STM32MP1 - - Set BL sizes regardless of flags - - - QEMU - - Include gicv2.mk for compiling GICv2 source files - - Change DEVICE2 definition for MMU - - Added helper to calculate the position shift from MPIDR - - - QEMU SBSA - - Include libraries for Cortex-A72 - - Increase SHARED_RAM_SIZE - - Addes support in spm_mm for upto 512 cores - - Added support for topology handling - - - QTI - - Mandate SMC implementation - - - Xilinx - - Rename the IPI CRC checksum macro - - Use fno-jump-tables flag in CPPFLAGS - - - Xilinx versal - - Added the IPI CRC checksum macro support - - Mark IPI calls secure/non-secure - - Enable sgi to communicate with linux using IPI - - Remove Cortex-A53 compilation - - - Xilinx ZynqMP - - Configure counter frequency during initialization - - Filter errors related to clock gate permissions - - Implement pinctrl request/release EEMI API - - Reimplement pinctrl get/set config parameter EEMI API calls - - Reimplement pinctrl set/get function EEMI API - - Update error codes to match Linux and PMU Firmware - - Update PM version and support PM version check - - Update return type in query functions - - Added missing ids for 43/46/47dr devices - - Checked for DLL status before doing reset - - Disable ITAPDLYENA bit for zero ITAP delay - - Include GICv2 makefile - - Remove the custom crash implementation - -- Services - - - SPMD - - Lock the g_spmd_pm structure - - Declare third cactus instance as UP SP - - Provide number of vCPUs and VM size for first SP - - Remove ``chosen`` node from SPMC manifests - - Move OP-TEE SP manifest DTS to FVP platform - - Update OP-TEE SP manifest with device-regions node - - Remove device-memory node from SPMC manifests - - - SPM_MM - - Use sp_boot_info to set SP context - - - SDEI - - Updata the affinity of shared event - -- Tools - - FIPtool - - Do not print duplicate verbose lines about building fiptool - - - CertCreate - - Updated tool for platform defined certs, keys & extensions - - Create only requested certificates - - Avoid duplicates in extension stack - -Resolved Issues -^^^^^^^^^^^^^^^ -- Several fixes for typos and mis-spellings in documentation - -- Build system - - Fixed ${FIP_NAME} to be rebuilt only when needed in Makefile - - Do not mark file targets as .PHONY target in Makefile - -- Drivers - - Authorization - - Avoid NV counter upgrade without certificate validation - - - Arm GICv3 - - Fixed logical issue for num_eints - - Limit SPI ID to avoid misjudgement in GICD_OFFSET() - - Fixed potential GICD context override with ESPI enabled - - - Marvell A3700 - - Fixed configuring polarity invert bits - - - Arm TZC-400 - - Correct FAIL_CONTROL Privileged bit - - Fixed logical error in FILTER_BIT definitions - - - Renesas rcar - - Fixed several coding style violations reported by checkpatch - -- Libraries - - Arch helpers - - Fixed assertions in processing dynamic relocations for AArch64 builds - - - C standard library - - Fixed MISRA issues in memset() ABI - - - RAS - - Fixed bug of binary search in RAS interrupt handler - -- Platforms - - - Arm - - Fixed missing copyrights in arm-gic.h file - - Fixed the order of header files in several dts files - - Fixed error message printing in board makefile - - Fixed bug of overriding the last node in image load helper API - - Fixed stdout-path in fdts files of TC0 and N1SDP platforms - - Turn ON/OFF redistributor in sync with GIC CPU interface ON/OFF for css platforms - - - Arm FVP - - Fixed Generic Timer interrupt types in platform dts files - - - Arm Juno - - Fixed parallel build issue for romlib config - - - Arm SGI - - Fixed bug in SDEI receive event of RAS handler - - - Intel Agilex - - Fixed PLAT_MAX_PWR_LVL value - - - Marvell - - Fixed SPD handling in dram port - - - Marvell ARMADA - - Fixed TRNG return SMC handling - - Fixed the logic used for LD selector mask - - Fixed MSS firmware loader for A8K family - - - ST - - Fixed few violations reported by coverity static checks - - - STM32MP1 - - Fixed SELFREF_TO_X32 mask in ddr driver - - Do not keep mmc_device_info in stack - - Correct plat_crash_console_flush() - - - QEMU SBSA - - Fixed memory type of secure NOR flash - - - QTI - - Fixed NUM_APID and REG_APID_MAP() argument in SPMI driver - - - Intel - - Do not keep mmc_device_info in stack - - - Hisilicon - - Do not keep mmc_device_info in stack - - -- Services - - - EL3 runtime - - Fixed the EL2 context save/restore routine by removing EL2 generic - timer system registers - - Added fix for exception handler in BL31 by synchronizing pending EA - using DSB barrier - - - SPMD - - Fixed error codes to use int32_t type - - - TSPD - - Added bug fix in tspd interrupt handling when TSP_NS_INTR_ASYNC_PREEMPT is enabled - - - TRNG - - Fixed compilation errors with -O0 compile option - - - DebugFS - - Checked channel index before calling clone function - - - PSCI - - Fixed limit of 256 CPUs caused by cast to unsigned char - - - TSP - - Fixed compilation erros when built with GCC 11.0.0 toolchain - -- Tools - - FIPtool - - Do not call ``make clean`` for ``all`` target - - - CertCreate - - Fixed bug to avoid cleaning when building the binary - - Used preallocated parts of the HASH struct to avoid leaking HASH struct fields - - Free arguments copied with strdup - - Free keys after use - - Free X509_EXTENSION structures on stack to avoid leaking them - - Optimized the code to avoid unnecessary attempts to create non-requested - certificates - -Version 2.4 ------------ - -New Features -^^^^^^^^^^^^ - -- Architecture support - - Armv8.6-A - - Added support for Armv8.6 Enhanced Counter Virtualization (ECV) - - Added support for Armv8.6 Fine Grained Traps (FGT) - - Added support for Armv8.6 WFE trap delays - -- Bootloader images - - Added support for Measured Boot - -- Build System - - Added build option ``COT_DESC_IN_DTB`` to create Chain of Trust at runtime - - Added build option ``OPENSSL_DIR`` to direct tools to OpenSSL libraries - - Added build option ``RAS_TRAP_LOWER_EL_ERR_ACCESS`` to enable trapping RAS - register accesses from EL1/EL2 to EL3 - - Extended build option ``BRANCH_PROTECTION`` to support branch target - identification - -- Common components - - Added support for exporting CPU nodes to the device tree - - Added support for single and dual-root Chains of Trust in secure - partitions - -- Drivers - - Added Broadcom RNG driver - - Added Marvell ``mg_conf_cm3`` driver - - Added System Control and Management Interface (SCMI) driver - - Added STMicroelectronics ETZPC driver - - - Arm GICv3 - - Added support for detecting topology at runtime - - - Dual Root - - Added support for platform certificates - - - Marvell Cache LLC - - Added support for mapping the entire LLC into SRAM - - - Marvell CCU - - Added workaround for erratum 3033912 - - - Marvell CP110 COMPHY - - Added support for SATA COMPHY polarity inversion - - Added support for USB COMPHY polarity inversion - - Added workaround for erratum IPCE_COMPHY-1353 - - - STM32MP1 Clocks - - Added ``RTC`` as a gateable clock - - Added support for shifted clock selector bit masks - - Added support for using additional clocks as parents - -- Libraries - - C standard library - - Added support for hexadecimal and pointer format specifiers in - ``snprint()`` - - Added assembly alternatives for various library functions - - - CPU support - - Arm Cortex-A53 - - Added workaround for erratum 1530924 - - - Arm Cortex-A55 - - Added workaround for erratum 1530923 - - - Arm Cortex-A57 - - Added workaround for erratum 1319537 - - - Arm Cortex-A76 - - Added workaround for erratum 1165522 - - Added workaround for erratum 1791580 - - Added workaround for erratum 1868343 - - - Arm Cortex-A72 - - Added workaround for erratum 1319367 - - - Arm Cortex-A77 - - Added workaround for erratum 1508412 - - Added workaround for erratum 1800714 - - Added workaround for erratum 1925769 - - - Arm Neoverse-N1 - - Added workaround for erratum 1868343 - - - EL3 Runtime - - Added support for saving/restoring registers related to nested - virtualization in EL2 context switches if the architecture supports it - - - FCONF - - Added support for Measured Boot - - Added support for populating Chain of Trust properties - - Added support for loading the ``fw_config`` image - - - Measured Boot - - Added support for event logging - -- Platforms - - Added support for Arm Morello - - Added support for Arm TC0 - - Added support for iEi PUZZLE-M801 - - Added support for Marvell OCTEON TX2 T9130 - - Added support for MediaTek MT8192 - - Added support for NXP i.MX 8M Nano - - Added support for NXP i.MX 8M Plus - - Added support for QTI CHIP SC7180 - - Added support for STM32MP151F - - Added support for STM32MP153F - - Added support for STM32MP157F - - Added support for STM32MP151D - - Added support for STM32MP153D - - Added support for STM32MP157D - - - Arm - - Added support for platform-owned SPs - - Added support for resetting to BL31 - - - Arm FPGA - - Added support for Klein - - Added support for Matterhorn - - Added support for additional CPU clusters - - - Arm FVP - - Added support for performing SDEI platform setup at runtime - - Added support for SMCCC's ``SMCCC_ARCH_SOC_ID`` command - - Added an ``id`` field under the NV-counter node in the device tree to - differentiate between trusted and non-trusted NV-counters - - Added support for extracting the clock frequency from the timer node - in the device tree - - - Arm Juno - - Added support for SMCCC's ``SMCCC_ARCH_SOC_ID`` command - - - Arm N1SDP - - Added support for cross-chip PCI-e - - - Marvell - - Added support for AVS reduction - - - Marvell ARMADA - - Added support for twin-die combined memory device - - - Marvell ARMADA A8K - - Added support for DDR with 32-bit bus width (both ECC and non-ECC) - - - Marvell AP806 - - Added workaround for erratum FE-4265711 - - - Marvell AP807 - - Added workaround for erratum 3033912 - - - Nvidia Tegra - - Added debug printouts indicating SC7 entry sequence completion - - Added support for SDEI - - Added support for stack protection - - Added support for GICv3 - - Added support for SMCCC's ``SMCCC_ARCH_SOC_ID`` command - - - Nvidia Tegra194 - - Added support for RAS exception handling - - Added support for SPM - - - NXP i.MX - - Added support for SDEI - - - QEMU SBSA - - Added support for the Secure Partition Manager - - - QTI - - Added RNG driver - - Added SPMI PMIC arbitrator driver - - Added support for SMCCC's ``SMCCC_ARCH_SOC_ID`` command - - - STM32MP1 - - Added support for exposing peripheral interfaces to the non-secure - world at runtime - - Added support for SCMI clock and reset services - - Added support for STM32MP15x CPU revision Z - - Added support for SMCCC services in ``SP_MIN`` - -- Services - - Secure Payload Dispatcher - - Added a provision to allow clients to retrieve the service UUID - - - SPMC - - Added secondary core endpoint information to the SPMC context - structure - - - SPMD - - Added support for booting OP-TEE as a guest S-EL1 Secure Partition on - top of Hafnium in S-EL2 - - Added a provision for handling SPMC messages to register secondary - core entry points - - Added support for power management operations - -- Tools - - CertCreate - - Added support for secure partitions - - - CertTool - - Added support for the ``fw_config`` image - - - FIPTool - - Added support for the ``fw_config`` image - -Changed -^^^^^^^ - -- Architecture support - -- Bootloader images - -- Build System - - The top-level Makefile now supports building FipTool on Windows - - The default value of ``KEY_SIZE`` has been changed to to 2048 when RSA is - in use - - The previously-deprecated macro ``__ASSEMBLY__`` has now been removed - -- Common components - - Certain functions that flush the console will no longer return error - information - -- Drivers - - Arm GIC - - Usage of ``drivers/arm/gic/common/gic_common.c`` has now been - deprecated in favour of ``drivers/arm/gic/vX/gicvX.mk`` - - Added support for detecting the presence of a GIC600-AE - - Added support for detecting the presence of a GIC-Clayton - - - Marvell MCI - - Now performs link tuning for all MCI interfaces to improve performance - - - Marvell MoChi - - PIDI masters are no longer forced into a non-secure access level when - ``LLC_SRAM`` is enabled - - The SD/MMC controllers are now accessible from guest virtual machines - - - Mbed TLS - - Migrated to Mbed TLS v2.24.0 - - - STM32 FMC2 NAND - - Adjusted FMC node bindings to include an EBI controller node - - - STM32 Reset - - Added an optional timeout argument to assertion functions - - - STM32MP1 Clocks - - Enabled several additional system clocks during initialization - -- Libraries - - C Standard Library - - Improved ``memset`` performance by avoiding single-byte writes - - Added optimized assembly variants of ``memset`` - - - CPU support - - Renamed Cortex-Hercules to Cortex-A78 - - Renamed Cortex-Hercules AE to Cortex-A78 AE - - Renamed Neoverse Zeus to Neoverse V1 - - - Coreboot - - Updated ‘coreboot_get_memory_type’ API to take an extra argument as a - ’memory size’ that used to return a valid memory type. - - - libfdt - - Updated to latest upstream version - -- Platforms - - Allwinner - - Disabled non-secure access to PRCM power control registers - - - Arm - - ``BL32_BASE`` is now platform-dependent when ``SPD_spmd`` is enabled - - Added support for loading the Chain of Trust from the device tree - - The firmware update check is now executed only once - - NV-counter base addresses are now loaded from the device tree when - ``COT_DESC_IN_DTB`` is enabled - - Now loads and populates ``fw_config`` and ``tb_fw_config`` - - FCONF population now occurs after caches have been enabled in order - to reduce boot times - - - Arm Corstone-700 - - Platform support has been split into both an FVP and an FPGA variant - - - Arm FPGA - - DTB and BL33 load addresses have been given sensible default values - - Now reads generic timer counter frequency, GICD and GICR base - addresses, and UART address from DT - - Now treats the primary PL011 UART as an SBSA Generic UART - - - Arm FVP - - Secure interrupt descriptions, UART parameters, clock frequencies and - GICv3 parameters are now queried through FCONF - - UART parameters are now queried through the device tree - - Added an owner field to Cactus secure partitions - - Increased the maximum size of BL2 when the Chain of Trust is loaded - from the device tree - - Reduces the maximum size of BL31 - - The ``FVP_USE_SP804_TIMER`` and ``FVP_VE_USE_SP804_TIMER`` build - options have been removed in favour of a common ``USE_SP804_TIMER`` - option - - Added a third Cactus partition to manifests - - Device tree nodes now store UUIDs in big-endian - - - Arm Juno - - Increased the maximum size of BL2 when optimizations have not been - applied - - Reduced the maximum size of BL31 and BL32 - - - Marvell AP807 - - Enabled snoop filters - - - Marvell ARMADA A3K - - UART recovery images are now suffixed with ``.bin`` - - - Marvell ARMADA A8K - - Option ``BL31_CACHE_DISABLE`` is now disabled (``0``) by default - - - Nvidia Tegra - - Added VPR resize supported check when processing video memory resize - requests - - Added SMMU verification to prevent potential issues caused by - undetected corruption of the SMMU configuration during boot - - The GIC CPU interface is now properly disabled after CPU off - - The GICv2 sources list and the ``BL31_SIZE`` definition have been made - platform-specific - - The SPE driver will no longer flush the console when writing - individual characters - - - Nvidia Tegra194 - - TZDRAM setup has been moved to platform-specific early boot handlers - - Increased verbosity of debug prints for RAS SErrors - - Support for powering down CPUs during CPU suspend has been removed - - Now verifies firewall settings before using resources - - - TI K3 - - The UART number has been made configurable through ``K3_USART`` - - - Rockchip RK3368 - - The maximum number of memory map regions has been increased to 20 - - - Socionext Uniphier - - The maximum size of BL33 has been increased to support larger - bootloaders - - - STM32 - - Removed platform-specific DT functions in favour of using existing - generic alternatives - - - STM32MP1 - - Increased verbosity of exception reports in debug builds - - Device trees have been updated to align with the Linux kernel - - Now uses the ETZPC driver to configure secure-aware interfaces for - assignment to the non-secure world - - Finished good variants have been added to the board identifier - enumerations - - Non-secure access to clocks and reset domains now depends on their - state of registration - - NEON is now disabled in ``SP_MIN`` - - The last page of ``SYSRAM`` is now used as SCMI shared memory - - Checks to verify platform compatibility have been added to verify that - an image is compatible with the chip ID of the running platform - - - QEMU SBSA - - Removed support for Arm's Cortex-A53 - -- Services - - Renamed SPCI to FF-A - - - SPMD - - No longer forwards requests to the non-secure world when retrieving - partition information - - SPMC manifest size is now retrieved directly from SPMD instead of the - device tree - - The FF-A version handler now returns SPMD's version when the origin - of the call is secure, and SPMC's version when the origin of the call - is non-secure - - - SPMC - - Updated the manifest to declare CPU nodes in descending order as per - the SPM (Hafnium) multicore requirement - - Updated the device tree to mark 2GB as device memory for the first - partition excluding trusted DRAM region (which is reserved for SPMC) - - Increased the number of EC contexts to the maximum number of PEs as - per the FF-A specification - -- Tools - - FIPTool - - Now returns ``0`` on ``help`` and ``help `` - - - Marvell DoImage - - Updated Mbed TLS support to v2.8 - - - SPTool - - Now appends CertTool arguments - -Resolved Issues -^^^^^^^^^^^^^^^ - -- Bootloader images - - Fixed compilation errors for dual-root Chains of Trust caused by symbol - collision - - - BL31 - - Fixed compilation errors on platforms with fewer than 4 cores caused - by initialization code exceeding the end of the stacks - - Fixed compilation errors when building a position-independent image - -- Build System - - Fixed invalid empty version strings - - Fixed compilation errors on Windows caused by a non-portable architecture - revision comparison - -- Drivers - - Arm GIC - - Fixed spurious interrupts caused by a missing barrier - - - STM32 Flexible Memory Controller 2 (FMC2) NAND driver - - Fixed runtime instability caused by incorrect error detection logic - - - STM32MP1 Clock driver - - Fixed incorrectly-formatted log messages - - Fixed runtime instability caused by improper clock gating procedures - - - STMicroelectronics Raw NAND driver - - Fixed runtime instability caused by incorrect unit conversion when - waiting for NAND readiness - -- Libraries - - AMU - - Fixed timeout errors caused by excess error logging - - - EL3 Runtime - - Fixed runtime instability caused by improper register save/restore - routine in EL2 - - - FCONF - - Fixed failure to initialize GICv3 caused by overly-strict device tree - requirements - - - Measured Boot - - Fixed driver errors caused by a missing default value for the - ``HASH_ALG`` build option - - - SPE - - Fixed feature detection check that prevented CPUs supporting SVE from - detecting support for SPE in the non-secure world - - - Translation Tables - - Fixed various MISRA-C 2012 static analysis violations - -- Platforms - - Allwinner A64 - - Fixed USB issues on certain battery-powered device caused by - improperly activated USB power rail - - - Arm - - Fixed compilation errors caused by increase in BL2 size - - Fixed compilation errors caused by missing Makefile dependencies to - generated files when building the FIP - - Fixed MISRA-C 2012 static analysis violations caused by unused - structures in include directives intended to be feature-gated - - - Arm FPGA - - Fixed initialization issues caused by incorrect MPIDR topology mapping - logic - - - Arm RD-N1-edge - - Fixed compilation errors caused by mismatched parentheses in Makefile - - - Arm SGI - - Fixed crashes due to the flash memory used for cold reboot attack - protection not being mapped - - - Intel Agilex - - Fixed initialization issues caused by several compounding bugs - - - Marvell - - Fixed compilation warnings caused by multiple Makefile inclusions - - - Marvell ARMADA A3K - - Fixed boot issue in debug builds caused by checks on the BL33 load - address that are not appropriate for this platform - - - Nvidia Tegra - - Fixed incorrect delay timer reads - - Fixed spurious interrupts in the non-secure world during cold boot - caused by the arbitration bit in the memory controller not being - cleared - - Fixed faulty video memory resize sequence - - - Nvidia Tegra194 - - Fixed incorrect alignment of TZDRAM base address - - - NXP iMX8M - - Fixed CPU hot-plug issues caused by race condition - - - STM32MP1 - - Fixed compilation errors in highly-parallel builds caused by incorrect - Makefile dependencies - - - STM32MP157C-ED1 - - Fixed initialization issues caused by missing device tree hash node - - - Raspberry Pi 3 - - Fixed compilation errors caused by incorrect dependency ordering in - Makefile - - - Rockchip - - Fixed initialization issues caused by non-critical errors when parsing - FDT being treated as critical - - - Rockchip RK3368 - - Fixed runtime instability caused by incorrect CPUID shift value - - - QEMU - - Fixed compilation errors caused by incorrect dependency ordering in - Makefile - - - QEMU SBSA - - Fixed initialization issues caused by FDT exceeding reserved memory - size - - - QTI - - Fixed compilation errors caused by inclusion of a non-existent file - -- Services - - FF-A (previously SPCI) - - Fixed SPMD aborts caused by incorrect behaviour when the manifest is - page-aligned - -- Tools - - Fixed compilation issues when compiling tools from within their respective - directories - - - FIPTool - - Fixed command line parsing issues on Windows when using arguments - whose names also happen to be a subset of another's - - - Marvell DoImage - - Fixed PKCS signature verification errors at boot on some platforms - caused by generation of misaligned images - -Known Issues -^^^^^^^^^^^^ - -- Platforms - - NVIDIA Tegra - - Signed comparison compiler warnings occurring in libfdt are currently - being worked around by disabling the warning for the platform until - the underlying issue is resolved in libfdt - -Version 2.3 ------------ - -New Features -^^^^^^^^^^^^ - -- Arm Architecture - - Add support for Armv8.4-SecEL2 extension through the SPCI defined SPMD/SPMC - components. - - - Build option to support EL2 context save and restore in the secure world - (CTX_INCLUDE_EL2_REGS). - - - Add support for SMCCC v1.2 (introducing the new SMCCC_ARCH_SOC_ID SMC). - Note that the support is compliant, but the SVE registers save/restore will - be done as part of future S-EL2/SPM development. - -- BL-specific - - Enhanced BL2 bootloader flow to load secure partitions based on firmware - configuration data (fconf). - - - Changes necessary to support SEPARATE_NOBITS_REGION feature - - - TSP and BL2_AT_EL3: Add Position Independent Execution ``PIE`` support - -- Build System - - Add support for documentation build as a target in Makefile - - - Add ``COT`` build option to select the Chain of Trust to use when the - Trusted Boot feature is enabled (default: ``tbbr``). - - - Added creation and injection of secure partition packages into the FIP. - - - Build option to support SPMC component loading and run at S-EL1 - or S-EL2 (SPMD_SPM_AT_SEL2). - - - Enable MTE support - - - Enable Link Time Optimization in GCC - - - Enable -Wredundant-decls warning check - - - Makefile: Add support to optionally encrypt BL31 and BL32 - - - Add support to pass the nt_fw_config DTB to OP-TEE. - - - Introduce per-BL ``CPPFLAGS``, ``ASFLAGS``, and ``LDFLAGS`` - - - build_macros: Add CREATE_SEQ function to generate sequence of numbers - -- CPU Support - - cortex-a57: Enable higher performance non-cacheable load forwarding - - - Hercules: Workaround for Errata 1688305 - - - Klein: Support added for Klein CPU - - - Matterhorn: Support added for Matterhorn CPU - -- Drivers - - auth: Add ``calc_hash`` function for hash calculation. Used for - authentication of images when measured boot is enabled. - - - cryptocell: Add authenticated decryption framework, and support - for CryptoCell-713 and CryptoCell-712 RSA 3K - - - gic600: Add support for multichip configuration and Clayton - - gicv3: Introduce makefile, Add extended PPI and SPI range, - Add support for probing multiple GIC Redistributor frames - - gicv4: Add GICv4 extension for GIC driver - - - io: Add an IO abstraction layer to load encrypted firmwares - - - mhu: Derive doorbell base address - - - mtd: Add SPI-NOR, SPI-NAND, SPI-MEM, and raw NAND framework - - - scmi: Allow use of multiple SCMI channels - - - scu: Add a driver for snoop control unit - -- Libraries - - coreboot: Add memory range parsing and use generic base address - - - compiler_rt: Import popcountdi2.c and popcountsi2.c files, - aeabi_ldivmode.S file and dependencies - - - debugFS: Add DebugFS functionality - - - el3_runtime: Add support for enabling S-EL2 - - - fconf: Add Firmware Configuration Framework (fconf) (experimental). - - - libc: Add memrchr function - - - locks: bakery: Use is_dcache_enabled() helper and add a DMB to - the 'read_cache_op' macro - - - psci: Add support to enable different personality of the same soc. - - - xlat_tables_v2: Add support to pass shareability attribute for - normal memory region, use get_current_el_maybe_constant() in - is_dcache_enabled(), read-only xlat tables for BL31 memory, and - add enable_mmu() - -- New Platforms Support - - arm/arm_fpga: New platform support added for FPGA - - - arm/rddaniel: New platform support added for rd-daniel platform - - - brcm/stingray: New platform support added for Broadcom stingray platform - - - nvidia/tegra194: New platform support for Nvidia Tegra194 platform - -- Platforms - - allwinner: Implement PSCI system suspend using SCPI, add a msgbox - driver for use with SCPI, and reserve and map space for the SCP firmware - - allwinner: axp: Add AXP805 support - - allwinner: power: Add DLDO4 power rail - - - amlogic: axg: Add a build flag when using ATOS as BL32 and support for - the A113D (AXG) platform - - - arm/a5ds: Add ethernet node and L2 cache node in devicetree - - - arm/common: Add support for the new `dualroot` chain of trust - - arm/common: Add support for SEPARATE_NOBITS_REGION - - arm/common: Re-enable PIE when RESET_TO_BL31=1 - - arm/common: Allow boards to specify second DRAM Base address - and to define PLAT_ARM_TZC_FILTERS - - - arm/corstone700: Add support for mhuv2 and stack protector - - - arm/fvp: Add support for fconf in BL31 and SP_MIN. Populate power - domain descriptor dynamically by leveraging fconf APIs. - - arm/fvp: Add Cactus/Ivy Secure Partition information and use two - instances of Cactus at S-EL1 - - arm/fvp: Add support to run BL32 in TDRAM and BL31 in secure DRAM - - arm/fvp: Add support for GICv4 extension and BL2 hash calculation in BL1 - - - arm/n1sdp: Setup multichip gic routing table, update platform macros - for dual-chip setup, introduce platform information SDS region, add - support to update presence of External LLC, and enable the - NEOVERSE_N1_EXTERNAL_LLC flag - - - arm/rdn1edge: Add support for dual-chip configuration and use - CREATE_SEQ helper macro to compare chip count - - - arm/sgm: Always use SCMI for SGM platforms - - arm/sgm775: Add support for dynamic config using fconf - - - arm/sgi: Add multi-chip mode parameter in HW_CONFIG dts, macros for - remote chip device region, chip_id and multi_chip_mode to platform - variant info, and introduce number of chips macro - - - brcm: Add BL2 and BL31 support common across Broadcom platforms - - brcm: Add iproc SPI Nor flash support, spi driver, emmc driver, - and support to retrieve plat_toc_flags - - - hisilicon: hikey960: Enable system power off callback - - - intel: Enable bridge access, SiP SMC secure register access, and uboot - entrypoint support - - intel: Implement platform specific system reset 2 - - intel: Introduce mailbox response length handling - - - imx: console: Use CONSOLE_T_BASE for UART base address and generic console_t - data structure - - imx8mm: Provide uart base as build option and add the support for opteed spd - on imx8mq/imx8mm - - imx8qx: Provide debug uart num as build - - imx8qm: Apply clk/pinmux configuration for DEBUG_CONSOLE and provide debug - uart num as build param - - - marvell: a8k: Implement platform specific power off and add support - for loading MG CM3 images - - - mediatek: mt8183: Add Vmodem/Vcore DVS init level - - - qemu: Support optional encryption of BL31 and BL32 images - and ARM_LINUX_KERNEL_AS_BL33 to pass FDT address - - qemu: Define ARMV7_SUPPORTS_VFP - - qemu: Implement PSCI_CPU_OFF and qemu_system_off via semihosting - - - renesas: rcar_gen3: Add new board revision for M3ULCB - - - rockchip: Enable workaround for erratum 855873, claim a macro to enable - hdcp feature for DP, enable power domains of rk3399 before reset, add - support for UART3 as serial output, and initialize reset and poweroff - GPIOs with known invalid value - - - rpi: Implement PSCI CPU_OFF, use MMIO accessor, autodetect Mini-UART - vs. PL011 configuration, and allow using PL011 UART for RPi3/RPi4 - - rpi3: Include GPIO driver in all BL stages and use same "clock-less" - setup scheme as RPi4 - - rpi3/4: Add support for offlining CPUs - - - st: stm32mp1: platform.mk: Support generating multiple images in one build, - migrate to implicit rules, derive map file name from target name, generate - linker script with fixed name, and use PHONY for the appropriate targets - - st: stm32mp1: Add support for SPI-NOR, raw NAND, and SPI-NAND boot device, - QSPI, FMC2 driver - - st: stm32mp1: Use stm32mp_get_ddr_ns_size() function, set XN attribute for - some areas in BL2, dynamically map DDR later and non-cacheable during its - test, add a function to get non-secure DDR size, add DT helper for reg by - name, and add compilation flags for boot devices - - - socionext: uniphier: Turn on ENABLE_PIE - - - ti: k3: Add PIE support - - - xilinx: versal: Add set wakeup source, client wakeup, query data, request - wakeup, PM_INIT_FINALIZE, PM_GET_TRUSTZONE_VERSION, PM IOCTL, support for - suspend related, and Get_ChipID APIs - - xilinx: versal: Implement power down/restart related EEMI, SMC handler for - EEMI, PLL related PM, clock related PM, pin control related PM, reset related - PM, device related PM , APIs - - xilinx: versal: Enable ipi mailbox service - - xilinx: versal: Add get_api_version support and support to send PM API to PMC - using IPI - - xilinx: zynqmp: Add checksum support for IPI data, GET_CALLBACK_DATA - function, support to query max divisor, CLK_SET_RATE_PARENT in gem clock - node, support for custom type flags, LPD WDT clock to the pm_clock structure, - idcodes for new RFSoC silicons ZU48DR and ZU49DR, and id for new RFSoC device - ZU39DR - -- Security - - Use Speculation Barrier instruction for v8.5+ cores - - - Add support for optional firmware encryption feature (experimental). - - - Introduce a new `dualroot` chain of trust. - - - aarch64: Prevent speculative execution past ERET - - aarch32: Stop speculative execution past exception returns. - -- SPCI - - Introduced the Secure Partition Manager Dispatcher (SPMD) component as a - new standard service. - -- Tools - - cert_create: Introduce CoT build option and TBBR CoT makefile, - and define the dualroot CoT - - - encrypt_fw: Add firmware authenticated encryption tool - - - memory: Add show_memory script that prints a representation - of the memory layout for the latest build - -Changed -^^^^^^^ - -- Arm Architecture - - PIE: Make call to GDT relocation fixup generalized - -- BL-Specific - - Increase maximum size of BL2 image - - - BL31: Discard .dynsym .dynstr .hash sections to make ENABLE_PIE work - - BL31: Split into two separate memory regions - - - Unify BL linker scripts and reduce code duplication. - -- Build System - - Changes to drive cert_create for dualroot CoT - - - Enable -Wlogical-op always - - - Enable -Wshadow always - - - Refactor the warning flags - - - PIE: Pass PIE options only to BL31 - - - Reduce space lost to object alignment - - - Set lld as the default linker for Clang builds - - - Remove -Wunused-const-variable and -Wpadded warning - - - Remove -Wmissing-declarations warning from WARNING1 level - -- Drivers - - authentication: Necessary fix in drivers to upgrade to mbedtls-2.18.0 - - - console: Integrate UART base address in generic console_t - - - gicv3: Change API for GICR_IPRIORITYR accessors and separate - GICD and GICR accessor functions - - - io: Change seek offset to signed long long and panic in case - of io setup failure - - - smmu: SMMUv3: Changed retry loop to delay timer - - - tbbr: Reduce size of hash and ECDSA key buffers when possible - -- Library Code - - libc: Consolidate the size_t, unified, and NULL definitions, - and unify intmax_t and uintmax_t on AArch32/64 - - - ROMLIB: Optimize memory layout when ROMLIB is used - - - xlat_tables_v2: Use ARRAY_SIZE in REGISTER_XLAT_CONTEXT_FULL_SPEC, - merge REGISTER_XLAT_CONTEXT_{FULL_SPEC,RO_BASE_TABLE}, - and simplify end address checks in mmap_add_region_check() - -- Platforms - - allwinner: Adjust SRAM A2 base to include the ARISC vectors, clean up MMU - setup, reenable USE_COHERENT_MEM, remove unused include path, move the - NOBITS region to SRAM A1, convert AXP803 regulator setup code into a driver, - enable clock before resetting I2C/RSB - - allwinner: h6: power: Switch to using the AXP driver - - allwinner: a64: power: Use fdt_for_each_subnode, remove obsolete register - check, remove duplicate DT check, and make sunxi_turn_off_soc static - - allwinner: Build PMIC bus drivers only in BL31, clean up PMIC-related error - handling, and synchronize PMIC enumerations - - - arm/a5ds: Change boot address to point to DDR address - - - arm/common: Check for out-of-bound accesses in the platform io policies - - - arm/corstone700: Updating the kernel arguments to support initramfs, - use fdts DDR memory and XIP rootfs, and set UART clocks to 32MHz - - - arm/fvp: Modify multithreaded dts file of DynamIQ FVPs, slightly bump - the stack size for bl1 and bl2, remove re-definition of topology related - build options, stop reclaiming init code with Clang builds, and map only - the needed DRAM region statically in BL31/SP_MIN - - - arm/juno: Maximize space allocated to SCP_BL2 - - - arm/sgi: Bump bl1 RW limit, mark remote chip shared ram as non-cacheable, - move GIC related constants to board files, include AFF3 affinity in core - position calculation, move bl31_platform_setup to board file, and move - topology information to board folder - - - common: Refactor load_auth_image_internal(). - - - hisilicon: Remove uefi-tools in hikey and hikey960 documentation - - - intel: Modify non secure access function, BL31 address mapping, mailbox's - get_config_status, and stratix10 BL31 parameter handling - - intel: Remove un-needed checks for qspi driver r/w and s10 unused source code - - intel: Change all global sip function to static - - intel: Refactor common platform code - - intel: Create SiP service header file - - - - marvell: armada: scp_bl2: Allow loading up to 8 images - - marvell: comphy-a3700: Support SGMII COMPHY power off and fix USB3 - powering on when on lane 2 - - marvell: Consolidate console register calls - - - mediatek: mt8183: Protect 4GB~8GB dram memory, refine GIC driver for - low power scenarios, and switch PLL/CLKSQ/ck_off/axi_26m control to SPM - - - qemu: Update flash address map to keep FIP in secure FLASH0 - - - renesas: rcar_gen3: Update IPL and Secure Monitor Rev.2.0.6, update DDR - setting for H3, M3, M3N, change fixed destination address of BL31 and BL32, - add missing #{address,size}-cells into generated DT, pass DT to OpTee OS, - and move DDR drivers out of staging - - - rockchip: Make miniloader ddr_parameter handling optional, cleanup securing - of ddr regions, move secure init to separate file, use base+size for secure - ddr regions, bring TZRAM_SIZE values in lined, and prevent macro expansion - in paths - - - rpi: Move plat_helpers.S to common - - rpi3: gpio: Simplify GPIO setup - - rpi4: Skip UART initialisation - - - st: stm32m1: Use generic console_t data structure, remove second - QSPI flash instance, update for FMC2 pin muxing, and reduce MAX_XLAT_TABLES - to 4 - - - socionext: uniphier: Make on-chip SRAM and I/O register regions configurable - - socionext: uniphier: Make PSCI related, counter control, UART, pinmon, NAND - controller, and eMMC controller base addresses configurable - - socionext: uniphier: Change block_addressing flag and the return value type - of .is_usb_boot() to bool - - socionext: uniphier: Run BL33 at EL2, call uniphier_scp_is_running() only - when on-chip STM is supported, define PLAT_XLAT_TABLES_DYNAMIC only for BL2, - support read-only xlat tables, use enable_mmu() in common function, shrink - UNIPHIER_ROM_REGION_SIZE, prepare uniphier_soc_info() for next SoC, extend - boot device detection for future SoCs, make all BL images completely - position-independent, make uniphier_mmap_setup() work with PIE, pass SCP - base address as a function parameter, set buffer offset and length for - io_block dynamically, and use more mmap_add_dynamic_region() for loading - images - - - spd/trusty: Disable error messages seen during boot, allow gic base to be - specified with GICD_BASE, and allow getting trusty memsize from BL32_MEM_SIZE - instead of TSP_SEC_MEM_SIZE - - - ti: k3: common: Enable ARM cluster power down and rename device IDs to - be more consistent - - ti: k3: drivers: ti_sci: Put sequence number in coherent memory and - remove indirect structure of const data - - - xilinx: Move ipi mailbox svc to xilinx common - - xilinx: zynqmp: Use GIC framework for warm restart - - xilinx: zynqmp: pm: Move custom clock flags to typeflags, remove - CLK_TOPSW_LSBUS from invalid clock list and rename FPD WDT clock ID - - xilinx: versal: Increase OCM memory size for DEBUG builds and adjust - cpu clock, Move versal_def.h and versal_private to include directory - -- Tools - - sptool: Updated sptool to accommodate building secure partition packages. - -Resolved Issues -^^^^^^^^^^^^^^^ - -- Arm Architecture - - Fix crash dump for lower EL - -- BL-Specific - - Bug fix: Protect TSP prints with lock - - - Fix boot failures on some builds linked with ld.lld. - -- Build System - - Fix clang build if CC is not in the path. - - - Fix 'BL stage' comment for build macros - -- Code Quality - - coverity: Fix various MISRA violations including null pointer violations, - C issues in BL1/BL2/BL31 and FDT helper functions, using boolean essential, - type, and removing unnecessary header file and comparisons to LONG_MAX in - debugfs devfip - - - Based on coding guidelines, replace all `unsigned long` depending on if - fixed based on AArch32 or AArch64. - - - Unify type of "cpu_idx" and Platform specific defines across PSCI module. - -- Drivers - - auth: Necessary fix in drivers to upgrade to mbedtls-2.18.0 - - - delay_timer: Fix non-standard frequency issue in udelay - - - gicv3: Fix compiler dependent behavior - - gic600: Fix include ordering according to the coding style and power up sequence - -- Library Code - - el3_runtime: Fix stack pointer maintenance on EA handling path, - fixup 'cm_setup_context' prototype, and adds TPIDR_EL2 register - to the context save restore routines - - - libc: Fix SIZE_MAX on AArch32 - - - locks: T589: Fix insufficient ordering guarantees in bakery lock - - - pmf: Fix 'tautological-constant-compare' error, Make the runtime - instrumentation work on AArch32, and Simplify PMF helper macro - definitions across header files - - - xlat_tables_v2: Fix assembler warning of PLAT_RO_XLAT_TABLES - -- Platforms - - allwinner: Fix H6 GPIO and CCU memory map addresses and incorrect ARISC - code patch offset check - - - arm/a5ds: Correct system freq and Cache Writeback Granule, and cleanup - enable-method in devicetree - - - arm/fvp: Fix incorrect GIC mapping, BL31 load address and image size - for RESET_TO_BL31=1, topology description of cpus for DynamIQ based - FVP, and multithreaded FVP power domain tree - - arm/fvp: spm-mm: Correcting instructions to build SPM for FVP - - - arm/common: Fix ROTPK hash generation for ECDSA encryption, BL2 bug in - dynamic configuration initialisation, and current RECLAIM_INIT_CODE behavior - - - arm/rde1edge: Fix incorrect topology tree description - - - arm/sgi: Fix the incorrect check for SCMI channel ID - - - common: Flush dcache when storing timestamp - - - intel: Fix UEFI decompression issue, memory calibration, SMC SIP service, - mailbox config return status, mailbox driver logic, FPGA manager on - reconfiguration, and mailbox send_cmd issue - - - imx: Fix shift-overflow errors, the rdc memory region slot's offset, - multiple definition of ipc_handle, missing inclusion of cdefs.h, and - correct the SGIs that used for secure interrupt - - - mediatek: mt8183: Fix AARCH64 init fail on CPU0 - - - rockchip: Fix definition of struct param_ddr_usage - - - rpi4: Fix documentation of armstub config entry - - - st: Correct io possible NULL pointer dereference and device_size type, - nand xor_ecc.val assigned value, static analysis tool issues, and fix - incorrect return value and correctly check pwr-regulators node - - - xilinx: zynqmp: Correct syscnt freq for QEMU and fix clock models - and IDs of GEM-related clocks - -Known Issues -^^^^^^^^^^^^ - -- Build System - - dtb: DTB creation not supported when building on a Windows host. - - This step in the build process is skipped when running on a Windows host. A - known issue from the 1.6 release. - - - Intermittent assertion firing `ASSERT: services/spd/tspd/tspd_main.c:105` - -- Coverity - - Intermittent Race condition in Coverity Jenkins Build Job - -- Platforms - - arm/juno: System suspend from Linux does not function as documented in the - user guide - - Following the instructions provided in the user guide document does not - result in the platform entering system suspend state as expected. A message - relating to the hdlcd driver failing to suspend will be emitted on the - Linux terminal. - - - mediatek/mt6795: This platform does not build in this release - -Version 2.2 ------------ - -New Features -^^^^^^^^^^^^ - -- Architecture - - Enable Pointer Authentication (PAuth) support for Secure World - - Adds support for ARMv8.3-PAuth in BL1 SMC calls and - BL2U image for firmware updates. - - - Enable Memory Tagging Extension (MTE) support in both secure and non-secure - worlds - - - Adds support for the new Memory Tagging Extension arriving in - ARMv8.5. MTE support is now enabled by default on systems that - support it at EL0. - - To enable it at ELx for both the non-secure and the secure - world, the compiler flag ``CTX_INCLUDE_MTE_REGS`` includes register - saving and restoring when necessary in order to prevent information - leakage between the worlds. - - - Add support for Branch Target Identification (BTI) - -- Build System - - Modify FVP makefile for CPUs that support both AArch64/32 - - - AArch32: Allow compiling with soft-float toolchain - - - Makefile: Add default warning flags - - - Add Makefile check for PAuth and AArch64 - - - Add compile-time errors for HW_ASSISTED_COHERENCY flag - - - Apply compile-time check for AArch64-only CPUs - - - build_macros: Add mechanism to prevent bin generation. - - - Add support for default stack-protector flag - - - spd: opteed: Enable NS_TIMER_SWITCH - - - plat/arm: Skip BL2U if RESET_TO_SP_MIN flag is set - - - Add new build option to let each platform select which implementation of spinlocks - it wants to use - -- CPU Support - - DSU: Workaround for erratum 798953 and 936184 - - - Neoverse N1: Force cacheable atomic to near atomic - - Neoverse N1: Workaround for erratum 1073348, 1130799, 1165347, 1207823, - 1220197, 1257314, 1262606, 1262888, 1275112, 1315703, 1542419 - - - Neoverse Zeus: Apply the MSR SSBS instruction - - - cortex-Hercules/HerculesAE: Support added for Cortex-Hercules and - Cortex-HerculesAE CPUs - - cortex-Hercules/HerculesAE: Enable AMU for Cortex-Hercules and Cortex-HerculesAE - - - cortex-a76AE: Support added for Cortex-A76AE CPU - - cortex-a76: Workaround for erratum 1257314, 1262606, 1262888, 1275112, - 1286807 - - - cortex-a65/a65AE: Support added for Cortex-A65 and Cortex-A65AE CPUs - - cortex-a65: Enable AMU for Cortex-A65 - - - cortex-a55: Workaround for erratum 1221012 - - - cortex-a35: Workaround for erratum 855472 - - - cortex-a9: Workaround for erratum 794073 - -- Drivers - - console: Allow the console to register multiple times - - - delay: Timeout detection support - - - gicv3: Enabled multi-socket GIC redistributor frame discovery and migrated - ARM platforms to the new API - - - Adds ``gicv3_rdistif_probe`` function that delegates the responsibility - of discovering the corresponding redistributor base frame to each CPU - itself. - - - sbsa: Add SBSA watchdog driver - - - st/stm32_hash: Add HASH driver - - - ti/uart: Add an AArch32 variant - -- Library at ROM (romlib) - - Introduce BTI support in Library at ROM (romlib) - -- New Platforms Support - - amlogic: g12a: New platform support added for the S905X2 (G12A) platform - - amlogic: meson/gxl: New platform support added for Amlogic Meson - S905x (GXL) - - - arm/a5ds: New platform support added for A5 DesignStart - - - arm/corstone: New platform support added for Corstone-700 - - - intel: New platform support added for Agilex - - - mediatek: New platform support added for MediaTek mt8183 - - - qemu/qemu_sbsa: New platform support added for QEMU SBSA platform - - - renesas/rcar_gen3: plat: New platform support added for D3 - - - rockchip: New platform support added for px30 - - rockchip: New platform support added for rk3288 - - - rpi: New platform support added for Raspberry Pi 4 - -- Platforms - - arm/common: Introduce wrapper functions to setup secure watchdog - - - arm/fvp: Add Delay Timer driver to BL1 and BL31 and option for defining - platform DRAM2 base - - arm/fvp: Add Linux DTS files for 32 bit threaded FVPs - - - arm/n1sdp: Add code for DDR ECC enablement and BL33 copy to DDR, Initialise CNTFRQ - in Non Secure CNTBaseN - - - arm/juno: Use shared mbedtls heap between BL1 and BL2 and add basic support for - dynamic config - - - imx: Basic support for PicoPi iMX7D, rdc module init, caam module init, - aipstz init, IMX_SIP_GET_SOC_INFO, IMX_SIP_BUILDINFO added - - - intel: Add ncore ccu driver - - - mediatek/mt81*: Use new bl31_params_parse() helper - - - nvidia: tegra: Add support for multi console interface - - - qemu/qemu_sbsa: Adding memory mapping for both FLASH0/FLASH1 - - qemu: Added gicv3 support, new console interface in AArch32, and sub-platforms - - - renesas/rcar_gen3: plat: Add R-Car V3M support, new board revision for H3ULCB, DBSC4 - setting before self-refresh mode - - - socionext/uniphier: Support console based on multi-console - - - st: stm32mp1: Add OP-TEE, Avenger96, watchdog, LpDDR3, authentication support - and general SYSCFG management - - - ti/k3: common: Add support for J721E, Use coherent memory for shared data, Trap all - asynchronous bus errors to EL3 - - - xilinx/zynqmp: Add support for multi console interface, Initialize IPI table from - zynqmp_config_setup() - -- PSCI - - Adding new optional PSCI hook ``pwr_domain_on_finish_late`` - - This PSCI hook ``pwr_domain_on_finish_late`` is similar to - ``pwr_domain_on_finish`` but is guaranteed to be invoked when the - respective core and cluster are participating in coherency. - -- Security - - Speculative Store Bypass Safe (SSBS): Further enhance protection against Spectre - variant 4 by disabling speculative loads/stores (SPSR.SSBS bit) by default. - - - UBSAN support and handlers - - Adds support for the Undefined Behaviour sanitizer. There are two types of - support offered - minimalistic trapping support which essentially immediately - crashes on undefined behaviour and full support with full debug messages. - -- Tools - - cert_create: Add support for bigger RSA key sizes (3KB and 4KB), - previously the maximum size was 2KB. - - - fiptool: Add support to build fiptool on Windows. - - -Changed -^^^^^^^ - -- Architecture - - Refactor ARMv8.3 Pointer Authentication support code - - - backtrace: Strip PAC field when PAUTH is enabled - - - Prettify crash reporting output on AArch64. - - - Rework smc_unknown return code path in smc_handler - - Leverage the existing ``el3_exit()`` return routine for smc_unknown return - path rather than a custom set of instructions. - -- BL-Specific - - Invalidate dcache build option for BL2 entry at EL3 - - - Add missing support for BL2_AT_EL3 in XIP memory - -- Boot Flow - - Add helper to parse BL31 parameters (both versions) - - - Factor out cross-BL API into export headers suitable for 3rd party code - - - Introduce lightweight BL platform parameter library - -- Drivers - - auth: Memory optimization for Chain of Trust (CoT) description - - - bsec: Move bsec_mode_is_closed_device() service to platform - - - cryptocell: Move Cryptocell specific API into driver - - - gicv3: Prevent pending G1S interrupt from becoming G0 interrupt - - - mbedtls: Remove weak heap implementation - - - mmc: Increase delay between ACMD41 retries - - mmc: stm32_sdmmc2: Correctly manage block size - - mmc: stm32_sdmmc2: Manage max-frequency property from DT - - - synopsys/emmc: Do not change FIFO TH as this breaks some platforms - - synopsys: Update synopsys drivers to not rely on undefined overflow behaviour - - - ufs: Extend the delay after reset to wait for some slower chips - -- Platforms - - amlogic/meson/gxl: Remove BL2 dependency from BL31 - - - arm/common: Shorten the Firmware Update (FWU) process - - - arm/fvp: Remove GIC initialisation from secondary core cold boot - - - arm/sgm: Temporarily disable shared Mbed TLS heap for SGM - - - hisilicon: Update hisilicon drivers to not rely on undefined overflow behaviour - - - imx: imx8: Replace PLAT_IMX8* with PLAT_imx8*, remove duplicated linker symbols and - deprecated code include, keep only IRQ 32 unmasked, enable all power domain by default - - - marvell: Prevent SError accessing PCIe link, Switch to xlat_tables_v2, do not rely on - argument passed via smc, make sure that comphy init will use correct address - - - mediatek: mt8173: Refactor RTC and PMIC drivers - - mediatek: mt8173: Apply MULTI_CONSOLE framework - - - nvidia: Tegra: memctrl_v2: fix "overflow before widen" coverity issue - - - qemu: Simplify the image size calculation, Move and generalise FDT PSCI fixup, move - gicv2 codes to separate file - - - renesas/rcar_gen3: Convert to multi-console API, update QoS setting, Update IPL and - Secure Monitor Rev2.0.4, Change to restore timer counter value at resume, Update DDR - setting rev.0.35, qos: change subslot cycle, Change periodic write DQ training option. - - - rockchip: Allow SOCs with undefined wfe check bits, Streamline and complete UARTn_BASE - macros, drop rockchip-specific imported linker symbols for bl31, Disable binary generation - for all SOCs, Allow console device to be set by DTB, Use new bl31_params_parse functions - - - rpi/rpi3: Move shared rpi3 files into common directory - - - socionext/uniphier: Set CONSOLE_FLAG_TRANSLATE_CRLF and clean up console driver - - socionext/uniphier: Replace DIV_ROUND_UP() with div_round_up() from utils_def.h - - - st/stm32mp: Split stm32mp_io_setup function, move stm32_get_gpio_bank_clock() to private - file, correctly handle Clock Spreading Generator, move oscillator functions to generic file, - realign device tree files with internal devs, enable RTCAPB clock for dual-core chips, use a - common function to check spinlock is available, move check_header() to common code - - - ti/k3: Enable SEPARATE_CODE_AND_RODATA by default, Remove shared RAM space, - Drop _ADDRESS from K3_USART_BASE to match other defines, Remove MSMC port - definitions, Allow USE_COHERENT_MEM for K3, Set L2 latency on A72 cores - -- PSCI - - PSCI: Lookup list of parent nodes to lock only once - -- Secure Partition Manager (SPM): SPCI Prototype - - Fix service UUID lookup - - - Adjust size of virtual address space per partition - - - Refactor xlat context creation - - - Move shim layer to TTBR1_EL1 - - - Ignore empty regions in resource description - -- Security - - Refactor SPSR initialisation code - - - SMMUv3: Abort DMA transactions - - For security DMA should be blocked at the SMMU by default unless explicitly - enabled for a device. SMMU is disabled after reset with all streams bypassing - the SMMU, and abortion of all incoming transactions implements a default deny - policy on reset. - - Moves ``bl1_platform_setup()`` function from arm_bl1_setup.c to FVP platforms' - fvp_bl1_setup.c and fvp_ve_bl1_setup.c files. - -- Tools - - cert_create: Remove RSA PKCS#1 v1.5 support - - -Resolved Issues -^^^^^^^^^^^^^^^ - -- Architecture - - Fix the CAS spinlock implementation by adding a missing DSB in ``spin_unlock()`` - - - AArch64: Fix SCTLR bit definitions - - Removes incorrect ``SCTLR_V_BIT`` definition and adds definitions for - ARMv8.3-Pauth `EnIB`, `EnDA` and `EnDB` bits. - - - Fix restoration of PAuth context - - Replace call to ``pauth_context_save()`` with ``pauth_context_restore()`` in - case of unknown SMC call. - -- BL-Specific Issues - - Fix BL31 crash reporting on AArch64 only platforms - -- Build System - - Remove several warnings reported with W=2 and W=1 - -- Code Quality Issues - - SCTLR and ACTLR are 32-bit for AArch32 and 64-bit for AArch64 - - Unify type of "cpu_idx" across PSCI module. - - Assert if power level value greater then PSCI_INVALID_PWR_LVL - - Unsigned long should not be used as per coding guidelines - - Reduce the number of memory leaks in cert_create - - Fix type of cot_desc_ptr - - Use explicit-width data types in AAPCS parameter structs - - Add python configuration for editorconfig - - BL1: Fix type consistency - - - Enable -Wshift-overflow=2 to check for undefined shift behavior - - Updated upstream platforms to not rely on undefined overflow behaviour - -- Coverity Quality Issues - - Remove GGC ignore -Warray-bounds - - Fix Coverity #261967, Infinite loop - - Fix Coverity #343017, Missing unlock - - Fix Coverity #343008, Side affect in assertion - - Fix Coverity #342970, Uninitialized scalar variable - -- CPU Support - - cortex-a12: Fix MIDR mask - -- Drivers - - console: Remove Arm console unregister on suspend - - - gicv3: Fix support for full SPI range - - - scmi: Fix wrong payload length - -- Library Code - - libc: Fix sparse warning for __assert() - - - libc: Fix memchr implementation - -- Platforms - - rpi: rpi3: Fix compilation error when stack protector is enabled - - - socionext/uniphier: Fix compilation fail for SPM support build config - - - st/stm32mp1: Fix TZC400 configuration against non-secure DDR - - - ti/k3: common: Fix RO data area size calculation - -- Security - - AArch32: Disable Secure Cycle Counter - - Changes the implementation for disabling Secure Cycle Counter. - For ARMv8.5 the counter gets disabled by setting ``SDCR.SCCD`` bit on - CPU cold/warm boot. For the earlier architectures PMCR register is - saved/restored on secure world entry/exit from/to Non-secure state, - and cycle counting gets disabled by setting PMCR.DP bit. - - AArch64: Disable Secure Cycle Counter - - For ARMv8.5 the counter gets disabled by setting ``MDCR_El3.SCCD`` bit on - CPU cold/warm boot. For the earlier architectures PMCR_EL0 register is - saved/restored on secure world entry/exit from/to Non-secure state, - and cycle counting gets disabled by setting PMCR_EL0.DP bit. - -Deprecations -^^^^^^^^^^^^ - -- Common Code - - Remove MULTI_CONSOLE_API flag and references to it - - - Remove deprecated `plat_crash_console_*` - - - Remove deprecated interfaces `get_afflvl_shift`, `mpidr_mask_lower_afflvls`, `eret` - - - AARCH32/AARCH64 macros are now deprecated in favor of ``__aarch64__`` - - - ``__ASSEMBLY__`` macro is now deprecated in favor of ``__ASSEMBLER__`` - -- Drivers - - console: Removed legacy console API - - console: Remove deprecated finish_console_register - - - tzc: Remove deprecated types `tzc_action_t` and `tzc_region_attributes_t` - -- Secure Partition Manager (SPM): - - Prototype SPCI-based SPM (services/std_svc/spm) will be replaced with alternative - methods of secure partitioning support. - -Known Issues -^^^^^^^^^^^^ - -- Build System Issues - - dtb: DTB creation not supported when building on a Windows host. - - This step in the build process is skipped when running on a Windows host. A - known issue from the 1.6 release. - -- Platform Issues - - arm/juno: System suspend from Linux does not function as documented in the - user guide - - Following the instructions provided in the user guide document does not - result in the platform entering system suspend state as expected. A message - relating to the hdlcd driver failing to suspend will be emitted on the - Linux terminal. - - - mediatek/mt6795: This platform does not build in this release - -Version 2.1 ------------ - -New Features -^^^^^^^^^^^^ - -- Architecture - - Support for ARMv8.3 pointer authentication in the normal and secure worlds - - The use of pointer authentication in the normal world is enabled whenever - architectural support is available, without the need for additional build - flags. - - Use of pointer authentication in the secure world remains an - experimental configuration at this time. Using both the ``ENABLE_PAUTH`` - and ``CTX_INCLUDE_PAUTH_REGS`` build flags, pointer authentication can be - enabled in EL3 and S-EL1/0. - - See the :ref:`Firmware Design` document for additional details on the use - of pointer authentication. - - - Enable Data Independent Timing (DIT) in EL3, where supported - -- Build System - - Support for BL-specific build flags - - - Support setting compiler target architecture based on ``ARM_ARCH_MINOR`` - build option. - - - New ``RECLAIM_INIT_CODE`` build flag: - - A significant amount of the code used for the initialization of BL31 is - not needed again after boot time. In order to reduce the runtime memory - footprint, the memory used for this code can be reclaimed after - initialization. - - Certain boot-time functions were marked with the ``__init`` attribute to - enable this reclamation. - -- CPU Support - - cortex-a76: Workaround for erratum 1073348 - - cortex-a76: Workaround for erratum 1220197 - - cortex-a76: Workaround for erratum 1130799 - - - cortex-a75: Workaround for erratum 790748 - - cortex-a75: Workaround for erratum 764081 - - - cortex-a73: Workaround for erratum 852427 - - cortex-a73: Workaround for erratum 855423 - - - cortex-a57: Workaround for erratum 817169 - - cortex-a57: Workaround for erratum 814670 - - - cortex-a55: Workaround for erratum 903758 - - cortex-a55: Workaround for erratum 846532 - - cortex-a55: Workaround for erratum 798797 - - cortex-a55: Workaround for erratum 778703 - - cortex-a55: Workaround for erratum 768277 - - - cortex-a53: Workaround for erratum 819472 - - cortex-a53: Workaround for erratum 824069 - - cortex-a53: Workaround for erratum 827319 - - - cortex-a17: Workaround for erratum 852423 - - cortex-a17: Workaround for erratum 852421 - - - cortex-a15: Workaround for erratum 816470 - - cortex-a15: Workaround for erratum 827671 - -- Documentation - - Exception Handling Framework documentation - - - Library at ROM (romlib) documentation - - - RAS framework documentation - - - Coding Guidelines document - -- Drivers - - ccn: Add API for setting and reading node registers - - Adds ``ccn_read_node_reg`` function - - Adds ``ccn_write_node_reg`` function - - - partition: Support MBR partition entries - - - scmi: Add ``plat_css_get_scmi_info`` function - - Adds a new API ``plat_css_get_scmi_info`` which lets the platform - register a platform-specific instance of ``scmi_channel_plat_info_t`` and - remove the default values - - - tzc380: Add TZC-380 TrustZone Controller driver - - - tzc-dmc620: Add driver to manage the TrustZone Controller within the - DMC-620 Dynamic Memory Controller - -- Library at ROM (romlib) - - Add platform-specific jump table list - - - Allow patching of romlib functions - - This change allows patching of functions in the romlib. This can be done by - adding "patch" at the end of the jump table entry for the function that - needs to be patched in the file jmptbl.i. - -- Library Code - - Support non-LPAE-enabled MMU tables in AArch32 - - - mmio: Add ``mmio_clrsetbits_16`` function - - 16-bit variant of ``mmio_clrsetbits`` - - - object_pool: Add Object Pool Allocator - - Manages object allocation using a fixed-size static array - - Adds ``pool_alloc`` and ``pool_alloc_n`` functions - - Does not provide any functions to free allocated objects (by design) - - - libc: Added ``strlcpy`` function - - - libc: Import ``strrchr`` function from FreeBSD - - - xlat_tables: Add support for ARMv8.4-TTST - - - xlat_tables: Support mapping regions without an explicitly specified VA - -- Math - - Added softudiv macro to support software division - -- Memory Partitioning And Monitoring (MPAM) - - Enabled MPAM EL2 traps (``MPAMHCR_EL2`` and ``MPAM_EL2``) - -- Platforms - - amlogic: Add support for Meson S905 (GXBB) - - - arm/fvp_ve: Add support for FVP Versatile Express platform - - - arm/n1sdp: Add support for Neoverse N1 System Development platform - - - arm/rde1edge: Add support for Neoverse E1 platform - - - arm/rdn1edge: Add support for Neoverse N1 platform - - - arm: Add support for booting directly to Linux without an intermediate - loader (AArch32) - - - arm/juno: Enable new CPU errata workarounds for A53 and A57 - - - arm/juno: Add romlib support - - Building a combined BL1 and ROMLIB binary file with the correct page - alignment is now supported on the Juno platform. When ``USE_ROMLIB`` is set - for Juno, it generates the combined file ``bl1_romlib.bin`` which needs to - be used instead of bl1.bin. - - - intel/stratix: Add support for Intel Stratix 10 SoC FPGA platform - - - marvell: Add support for Armada-37xx SoC platform - - - nxp: Add support for i.MX8M and i.MX7 Warp7 platforms - - - renesas: Add support for R-Car Gen3 platform - - - xilinx: Add support for Versal ACAP platforms - -- Position-Independent Executable (PIE) - - PIE support has initially been added to BL31. The ``ENABLE_PIE`` build flag is - used to enable or disable this functionality as required. - -- Secure Partition Manager - - New SPM implementation based on SPCI Alpha 1 draft specification - - A new version of SPM has been implemented, based on the SPCI (Secure - Partition Client Interface) and SPRT (Secure Partition Runtime) draft - specifications. - - The new implementation is a prototype that is expected to undergo intensive - rework as the specifications change. It has basic support for multiple - Secure Partitions and Resource Descriptions. - - The older version of SPM, based on MM (ARM Management Mode Interface - Specification), is still present in the codebase. A new build flag, - ``SPM_MM`` has been added to allow selection of the desired implementation. - This flag defaults to 1, selecting the MM-based implementation. - -- Security - - Spectre Variant-1 mitigations (``CVE-2017-5753``) - - - Use Speculation Store Bypass Safe (SSBS) functionality where available - - Provides mitigation against ``CVE-2018-19440`` (Not saving x0 to x3 - registers can leak information from one Normal World SMC client to another) - - -Changed -^^^^^^^ - -- Build System - - Warning levels are now selectable with ``W=<1,2,3>`` - - - Removed unneeded include paths in PLAT_INCLUDES - - - "Warnings as errors" (Werror) can be disabled using ``E=0`` - - - Support totally quiet output with ``-s`` flag - - - Support passing options to checkpatch using ``CHECKPATCH_OPTS=`` - - - Invoke host compiler with ``HOSTCC / HOSTCCFLAGS`` instead of ``CC / CFLAGS`` - - - Make device tree pre-processing similar to U-boot/Linux by: - - Creating separate ``CPPFLAGS`` for DT preprocessing so that compiler - options specific to it can be accommodated. - - Replacing ``CPP`` with ``PP`` for DT pre-processing - -- CPU Support - - Errata report function definition is now mandatory for CPU support files - - CPU operation files must now define a ``_errata_report`` function to - print errata status. This is no longer a weak reference. - -- Documentation - - Migrated some content from GitHub wiki to ``docs/`` directory - - - Security advisories now have CVE links - - - Updated copyright guidelines - -- Drivers - - console: The ``MULTI_CONSOLE_API`` framework has been rewritten in C - - - console: Ported multi-console driver to AArch32 - - - gic: Remove 'lowest priority' constants - - Removed ``GIC_LOWEST_SEC_PRIORITY`` and ``GIC_LOWEST_NS_PRIORITY``. - Platforms should define these if required, or instead determine the correct - priority values at runtime. - - - delay_timer: Check that the Generic Timer extension is present - - - mmc: Increase command reply timeout to 10 milliseconds - - - mmc: Poll eMMC device status to ensure ``EXT_CSD`` command completion - - - mmc: Correctly check return code from ``mmc_fill_device_info`` - -- External Libraries - - - libfdt: Upgraded from 1.4.2 to 1.4.6-9 - - - mbed TLS: Upgraded from 2.12 to 2.16 - - This change incorporates fixes for security issues that should be reviewed - to determine if they are relevant for software implementations using - Trusted Firmware-A. See the `mbed TLS releases`_ page for details on - changes from the 2.12 to the 2.16 release. - -- Library Code - - compiler-rt: Updated ``lshrdi3.c`` and ``int_lib.h`` with changes from - LLVM master branch (r345645) - - - cpu: Updated macro that checks need for ``CVE-2017-5715`` mitigation - - - libc: Made setjmp and longjmp C standard compliant - - - libc: Allowed overriding the default libc (use ``OVERRIDE_LIBC``) - - - libc: Moved setjmp and longjmp to the ``libc/`` directory - -- Platforms - - Removed Mbed TLS dependency from plat_bl_common.c - - - arm: Removed unused ``ARM_MAP_BL_ROMLIB`` macro - - - arm: Removed ``ARM_BOARD_OPTIMISE_MEM`` feature and build flag - - - arm: Moved several components into ``drivers/`` directory - - This affects the SDS, SCP, SCPI, MHU and SCMI components - - - arm/juno: Increased maximum BL2 image size to ``0xF000`` - - This change was required to accommodate a larger ``libfdt`` library - -- SCMI - - Optimized bakery locks when hardware-assisted coherency is enabled using the - ``HW_ASSISTED_COHERENCY`` build flag - -- SDEI - - Added support for unconditionally resuming secure world execution after - |SDEI| event processing completes - - |SDEI| interrupts, although targeting EL3, occur on behalf of the non-secure - world, and may have higher priority than secure world - interrupts. Therefore they might preempt secure execution and yield - execution to the non-secure |SDEI| handler. Upon completion of |SDEI| event - handling, resume secure execution if it was preempted. - -- Translation Tables (XLAT) - - Dynamically detect need for ``Common not Private (TTBRn_ELx.CnP)`` bit - - Properly handle the case where ``ARMv8.2-TTCNP`` is implemented in a CPU - that does not implement all mandatory v8.2 features (and so must claim to - implement a lower architecture version). - - -Resolved Issues -^^^^^^^^^^^^^^^ - -- Architecture - - Incorrect check for SSBS feature detection - - - Unintentional register clobber in AArch32 reset_handler function - -- Build System - - Dependency issue during DTB image build - - - Incorrect variable expansion in Arm platform makefiles - - - Building on Windows with verbose mode (``V=1``) enabled is broken - - - AArch32 compilation flags is missing ``$(march32-directive)`` - -- BL-Specific Issues - - bl2: ``uintptr_t is not defined`` error when ``BL2_IN_XIP_MEM`` is defined - - - bl2: Missing prototype warning in ``bl2_arch_setup`` - - - bl31: Omission of Global Offset Table (GOT) section - -- Code Quality Issues - - Multiple MISRA compliance issues - - - Potential NULL pointer dereference (Coverity-detected) - -- Drivers - - mmc: Local declaration of ``scr`` variable causes a cache issue when - invalidating after the read DMA transfer completes - - - mmc: ``ACMD41`` does not send voltage information during initialization, - resulting in the command being treated as a query. This prevents the - command from initializing the controller. - - - mmc: When checking device state using ``mmc_device_state()`` there are no - retries attempted in the event of an error - - - ccn: Incorrect Region ID calculation for RN-I nodes - - - console: ``Fix MULTI_CONSOLE_API`` when used as a crash console - - - partition: Improper NULL checking in gpt.c - - - partition: Compilation failure in ``VERBOSE`` mode (``V=1``) - -- Library Code - - common: Incorrect check for Address Authentication support - - - xlat: Fix XLAT_V1 / XLAT_V2 incompatibility - - The file ``arm_xlat_tables.h`` has been renamed to ``xlat_tables_compat.h`` - and has been moved to a common folder. This header can be used to guarantee - compatibility, as it includes the correct header based on - ``XLAT_TABLES_LIB_V2``. - - - xlat: armclang unused-function warning on ``xlat_clean_dcache_range`` - - - xlat: Invalid ``mm_cursor`` checks in ``mmap_add`` and ``mmap_add_ctx`` - - - sdei: Missing ``context.h`` header - -- Platforms - - common: Missing prototype warning for ``plat_log_get_prefix`` - - - arm: Insufficient maximum BL33 image size - - - arm: Potential memory corruption during BL2-BL31 transition - - On Arm platforms, the BL2 memory can be overlaid by BL31/BL32. The memory - descriptors describing the list of executable images are created in BL2 - R/W memory, which could be possibly corrupted later on by BL31/BL32 due - to overlay. This patch creates a reserved location in SRAM for these - descriptors and are copied over by BL2 before handing over to next BL - image. - - - juno: Invalid behaviour when ``CSS_USE_SCMI_SDS_DRIVER`` is not set - - In ``juno_pm.c`` the ``css_scmi_override_pm_ops`` function was used - regardless of whether the build flag was set. The original behaviour has - been restored in the case where the build flag is not set. - -- Tools - - fiptool: Incorrect UUID parsing of blob parameters - - - doimage: Incorrect object rules in Makefile - - -Deprecations -^^^^^^^^^^^^ - -- Common Code - - ``plat_crash_console_init`` function - - - ``plat_crash_console_putc`` function - - - ``plat_crash_console_flush`` function - - - ``finish_console_register`` macro - -- AArch64-specific Code - - helpers: ``get_afflvl_shift`` - - - helpers: ``mpidr_mask_lower_afflvls`` - - - helpers: ``eret`` - -- Secure Partition Manager (SPM) - - Boot-info structure - - -Known Issues -^^^^^^^^^^^^ - -- Build System Issues - - dtb: DTB creation not supported when building on a Windows host. - - This step in the build process is skipped when running on a Windows host. A - known issue from the 1.6 release. - -- Platform Issues - - arm/juno: System suspend from Linux does not function as documented in the - user guide - - Following the instructions provided in the user guide document does not - result in the platform entering system suspend state as expected. A message - relating to the hdlcd driver failing to suspend will be emitted on the - Linux terminal. - - - arm/juno: The firmware update use-cases do not work with motherboard - firmware version < v1.5.0 (the reset reason is not preserved). The Linaro - 18.04 release has MB v1.4.9. The MB v1.5.0 is available in Linaro 18.10 - release. - - - mediatek/mt6795: This platform does not build in this release - -Version 2.0 ------------ - -New Features -^^^^^^^^^^^^ - -- Removal of a number of deprecated APIs - - - A new Platform Compatibility Policy document has been created which - references a wiki page that maintains a listing of deprecated - interfaces and the release after which they will be removed. - - - All deprecated interfaces except the MULTI_CONSOLE_API have been removed - from the code base. - - - Various Arm and partner platforms have been updated to remove the use of - removed APIs in this release. - - - This release is otherwise unchanged from 1.6 release - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- No issues known at 1.6 release resolved in 2.0 release - -Known Issues -^^^^^^^^^^^^ - -- DTB creation not supported when building on a Windows host. This step in the - build process is skipped when running on a Windows host. Known issue from - 1.6 version. - -- As a result of removal of deprecated interfaces the Nvidia Tegra, Marvell - Armada 8K and MediaTek MT6795 platforms do not build in this release. - Also MediaTek MT8173, NXP QorIQ LS1043A, NXP i.MX8QX, NXP i.MX8QMa, - Rockchip RK3328, Rockchip RK3368 and Rockchip RK3399 platforms have not been - confirmed to be working after the removal of the deprecated interfaces - although they do build. - -Version 1.6 ------------ - -New Features -^^^^^^^^^^^^ - -- Addressing Speculation Security Vulnerabilities - - - Implement static workaround for CVE-2018-3639 for AArch32 and AArch64 - - - Add support for dynamic mitigation for CVE-2018-3639 - - - Implement dynamic mitigation for CVE-2018-3639 on Cortex-A76 - - - Ensure |SDEI| handler executes with CVE-2018-3639 mitigation enabled - -- Introduce RAS handling on AArch64 - - - Some RAS extensions are mandatory for Armv8.2 CPUs, with others - mandatory for Armv8.4 CPUs however, all extensions are also optional - extensions to the base Armv8.0 architecture. - - - The Armv8 RAS Extensions introduced Standard Error Records which are a - set of standard registers to configure RAS node policy and allow RAS - Nodes to record and expose error information for error handling agents. - - - Capabilities are provided to support RAS Node enumeration and iteration - along with individual interrupt registrations and fault injections - support. - - - Introduce handlers for Uncontainable errors, Double Faults and EL3 - External Aborts - -- Enable Memory Partitioning And Monitoring (MPAM) for lower EL's - - - Memory Partitioning And Monitoring is an Armv8.4 feature that enables - various memory system components and resources to define partitions. - Software running at various ELs can then assign themselves to the - desired partition to control their performance aspects. - - - When ENABLE_MPAM_FOR_LOWER_ELS is set to 1, EL3 allows - lower ELs to access their own MPAM registers without trapping to EL3. - This patch however, doesn't make use of partitioning in EL3; platform - initialisation code should configure and use partitions in EL3 if - required. - -- Introduce ROM Lib Feature - - - Support combining several libraries into a self-called "romlib" image, - that may be shared across images to reduce memory footprint. The romlib - image is stored in ROM but is accessed through a jump-table that may be - stored in read-write memory, allowing for the library code to be patched. - -- Introduce Backtrace Feature - - - This function displays the backtrace, the current EL and security state - to allow a post-processing tool to choose the right binary to interpret - the dump. - - - Print backtrace in assert() and panic() to the console. - -- Code hygiene changes and alignment with MISRA C-2012 guideline with fixes - addressing issues complying to the following rules: - - - MISRA rules 4.9, 5.1, 5.3, 5.7, 8.2-8.5, 8.8, 8.13, 9.3, 10.1, - 10.3-10.4, 10.8, 11.3, 11.6, 12.1, 14.4, 15.7, 16.1-16.7, 17.7-17.8, - 20.7, 20.10, 20.12, 21.1, 21.15, 22.7 - - - Clean up the usage of void pointers to access symbols - - - Increase usage of static qualifier to locally used functions and data - - - Migrated to use of u_register_t for register read/write to better - match AArch32 and AArch64 type sizes - - - Use int-ll64 for both AArch32 and AArch64 to assist in consistent - format strings between architectures - - - Clean up TF-A libc by removing non arm copyrighted implementations - and replacing them with modified FreeBSD and SCC implementations - -- Various changes to support Clang linker and assembler - - - The clang assembler/preprocessor is used when Clang is selected. However, - the clang linker is not used because it is unable to link TF-A objects - due to immaturity of clang linker functionality at this time. - -- Refactor support APIs into Libraries - - - Evolve libfdt, mbed TLS library and standard C library sources as - proper libraries that TF-A may be linked against. - -- CPU Enhancements - - - Add CPU support for Cortex-Ares and Cortex-A76 - - - Add AMU support for Cortex-Ares - - - Add initial CPU support for Cortex-Deimos - - - Add initial CPU support for Cortex-Helios - - - Implement dynamic mitigation for CVE-2018-3639 on Cortex-A76 - - - Implement Cortex-Ares erratum 1043202 workaround - - - Implement DSU erratum 936184 workaround - - - Check presence of fix for errata 843419 in Cortex-A53 - - - Check presence of fix for errata 835769 in Cortex-A53 - -- Translation Tables Enhancements - - - The xlat v2 library has been refactored in order to be reused by - different TF components at different EL's including the addition of EL2. - Some refactoring to make the code more generic and less specific to TF, - in order to reuse the library outside of this project. - -- SPM Enhancements - - - General cleanups and refactoring to pave the way to multiple partitions - support - -- SDEI Enhancements - - - Allow platforms to define explicit events - - - Determine client EL from NS context's SCR_EL3 - - - Make dispatches synchronous - - - Introduce jump primitives for BL31 - - - Mask events after CPU wakeup in |SDEI| dispatcher to conform to the - specification - -- Misc TF-A Core Common Code Enhancements - - - Add support for eXecute In Place (XIP) memory in BL2 - - - Add support for the SMC Calling Convention 2.0 - - - Introduce External Abort handling on AArch64 - External Abort routed to EL3 was reported as an unhandled exception - and caused a panic. This change enables Trusted Firmware-A to handle - External Aborts routed to EL3. - - - Save value of ACTLR_EL1 implementation-defined register in the CPU - context structure rather than forcing it to 0. - - - Introduce ARM_LINUX_KERNEL_AS_BL33 build option, which allows BL31 to - directly jump to a Linux kernel. This makes for a quicker and simpler - boot flow, which might be useful in some test environments. - - - Add dynamic configurations for BL31, BL32 and BL33 enabling support for - Chain of Trust (COT). - - - Make TF UUID RFC 4122 compliant - -- New Platform Support - - - Arm SGI-575 - - - Arm SGM-775 - - - Allwinner sun50i_64 - - - Allwinner sun50i_h6 - - - NXP QorIQ LS1043A - - - NXP i.MX8QX - - - NXP i.MX8QM - - - NXP i.MX7Solo WaRP7 - - - TI K3 - - - Socionext Synquacer SC2A11 - - - Marvell Armada 8K - - - STMicroelectronics STM32MP1 - -- Misc Generic Platform Common Code Enhancements - - - Add MMC framework that supports both eMMC and SD card devices - -- Misc Arm Platform Common Code Enhancements - - - Demonstrate PSCI MEM_PROTECT from el3_runtime - - - Provide RAS support - - - Migrate AArch64 port to the multi console driver. The old API is - deprecated and will eventually be removed. - - - Move BL31 below BL2 to enable BL2 overlay resulting in changes in the - layout of BL images in memory to enable more efficient use of available - space. - - - Add cpp build processing for dtb that allows processing device tree - with external includes. - - - Extend FIP io driver to support multiple FIP devices - - - Add support for SCMI AP core configuration protocol v1.0 - - - Use SCMI AP core protocol to set the warm boot entrypoint - - - Add support to Mbed TLS drivers for shared heap among different - BL images to help optimise memory usage - - - Enable non-secure access to UART1 through a build option to support - a serial debug port for debugger connection - -- Enhancements for Arm Juno Platform - - - Add support for TrustZone Media Protection 1 (TZMP1) - -- Enhancements for Arm FVP Platform - - - Dynamic_config: remove the FVP dtb files - - - Set DYNAMIC_WORKAROUND_CVE_2018_3639=1 on FVP by default - - - Set the ability to dynamically disable Trusted Boot Board - authentication to be off by default with DYN_DISABLE_AUTH - - - Add librom enhancement support in FVP - - - Support shared Mbed TLS heap between BL1 and BL2 that allow a - reduction in BL2 size for FVP - -- Enhancements for Arm SGI/SGM Platform - - - Enable ARM_PLAT_MT flag for SGI-575 - - - Add dts files to enable support for dynamic config - - - Add RAS support - - - Support shared Mbed TLS heap for SGI and SGM between BL1 and BL2 - -- Enhancements for Non Arm Platforms - - - Raspberry Pi Platform - - - Hikey Platforms - - - Xilinx Platforms - - - QEMU Platform - - - Rockchip rk3399 Platform - - - TI Platforms - - - Socionext Platforms - - - Allwinner Platforms - - - NXP Platforms - - - NVIDIA Tegra Platform - - - Marvell Platforms - - - STMicroelectronics STM32MP1 Platform - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- No issues known at 1.5 release resolved in 1.6 release - -Known Issues -^^^^^^^^^^^^ - -- DTB creation not supported when building on a Windows host. This step in the - build process is skipped when running on a Windows host. Known issue from - 1.5 version. - -Version 1.5 ------------ - -New features -^^^^^^^^^^^^ - -- Added new firmware support to enable RAS (Reliability, Availability, and - Serviceability) functionality. - - - Secure Partition Manager (SPM): A Secure Partition is a software execution - environment instantiated in S-EL0 that can be used to implement simple - management and security services. The SPM is the firmware component that - is responsible for managing a Secure Partition. - - - SDEI dispatcher: Support for interrupt-based |SDEI| events and all - interfaces as defined by the |SDEI| specification v1.0, see - `SDEI Specification`_ - - - Exception Handling Framework (EHF): Framework that allows dispatching of - EL3 interrupts to their registered handlers which are registered based on - their priorities. Facilitates firmware-first error handling policy where - asynchronous exceptions may be routed to EL3. - - Integrated the TSPD with EHF. - -- Updated PSCI support: - - - Implemented PSCI v1.1 optional features `MEM_PROTECT` and `SYSTEM_RESET2`. - The supported PSCI version was updated to v1.1. - - - Improved PSCI STAT timestamp collection, including moving accounting for - retention states to be inside the locks and fixing handling of wrap-around - when calculating residency in AArch32 execution state. - - - Added optional handler for early suspend that executes when suspending to - a power-down state and with data caches enabled. - - This may provide a performance improvement on platforms where it is safe - to perform some or all of the platform actions from `pwr_domain_suspend` - with the data caches enabled. - -- Enabled build option, BL2_AT_EL3, for BL2 to allow execution at EL3 without - any dependency on TF BL1. - - This allows platforms which already have a non-TF Boot ROM to directly load - and execute BL2 and subsequent BL stages without need for BL1. This was not - previously possible because BL2 executes at S-EL1 and cannot jump straight to - EL3. - -- Implemented support for SMCCC v1.1, including `SMCCC_VERSION` and - `SMCCC_ARCH_FEATURES`. - - Additionally, added support for `SMCCC_VERSION` in PSCI features to enable - discovery of the SMCCC version via PSCI feature call. - -- Added Dynamic Configuration framework which enables each of the boot loader - stages to be dynamically configured at runtime if required by the platform. - The boot loader stage may optionally specify a firmware configuration file - and/or hardware configuration file that can then be shared with the next boot - loader stage. - - Introduced a new BL handover interface that essentially allows passing of 4 - arguments between the different BL stages. - - Updated cert_create and fip_tool to support the dynamic configuration files. - The COT also updated to support these new files. - -- Code hygiene changes and alignment with MISRA guideline: - - - Fix use of undefined macros. - - - Achieved compliance with Mandatory MISRA coding rules. - - - Achieved compliance for following Required MISRA rules for the default - build configurations on FVP and Juno platforms : 7.3, 8.3, 8.4, 8.5 and - 8.8. - -- Added support for Armv8.2-A architectural features: - - - Updated translation table set-up to set the CnP (Common not Private) bit - for secure page tables so that multiple PEs in the same Inner Shareable - domain can use the same translation table entries for a given stage of - translation in a particular translation regime. - - - Extended the supported values of ID_AA64MMFR0_EL1.PARange to include the - 52-bit Physical Address range. - - - Added support for the Scalable Vector Extension to allow Normal world - software to access SVE functionality but disable access to SVE, SIMD and - floating point functionality from the Secure world in order to prevent - corruption of the Z-registers. - -- Added support for Armv8.4-A architectural feature Activity Monitor Unit (AMU) - extensions. - - In addition to the v8.4 architectural extension, AMU support on Cortex-A75 - was implemented. - -- Enhanced OP-TEE support to enable use of pageable OP-TEE image. The Arm - standard platforms are updated to load up to 3 images for OP-TEE; header, - pager image and paged image. - - The chain of trust is extended to support the additional images. - -- Enhancements to the translation table library: - - - Introduced APIs to get and set the memory attributes of a region. - - - Added support to manage both privilege levels in translation regimes that - describe translations for 2 Exception levels, specifically the EL1&0 - translation regime, and extended the memory map region attributes to - include specifying Non-privileged access. - - - Added support to specify the granularity of the mappings of each region, - for instance a 2MB region can be specified to be mapped with 4KB page - tables instead of a 2MB block. - - - Disabled the higher VA range to avoid unpredictable behaviour if there is - an attempt to access addresses in the higher VA range. - - - Added helpers for Device and Normal memory MAIR encodings that align with - the Arm Architecture Reference Manual for Armv8-A (Arm DDI0487B.b). - - - Code hygiene including fixing type length and signedness of constants, - refactoring of function to enable the MMU, removing all instances where - the virtual address space is hardcoded and added comments that document - alignment needed between memory attributes and attributes specified in - TCR_ELx. - -- Updated GIC support: - - - Introduce new APIs for GICv2 and GICv3 that provide the capability to - specify interrupt properties rather than list of interrupt numbers alone. - The Arm platforms and other upstream platforms are migrated to use - interrupt properties. - - - Added helpers to save / restore the GICv3 context, specifically the - Distributor and Redistributor contexts and architectural parts of the ITS - power management. The Distributor and Redistributor helpers also support - the implementation-defined part of GIC-500 and GIC-600. - - Updated the Arm FVP platform to save / restore the GICv3 context on system - suspend / resume as an example of how to use the helpers. - - Introduced a new TZC secured DDR carve-out for use by Arm platforms for - storing EL3 runtime data such as the GICv3 register context. - -- Added support for Armv7-A architecture via build option ARM_ARCH_MAJOR=7. - This includes following features: - - - Updates GICv2 driver to manage GICv1 with security extensions. - - - Software implementation for 32bit division. - - - Enabled use of generic timer for platforms that do not set - ARM_CORTEX_Ax=yes. - - - Support for Armv7-A Virtualization extensions [DDI0406C_C]. - - - Support for both Armv7-A platforms that only have 32-bit addressing and - Armv7-A platforms that support large page addressing. - - - Included support for following Armv7 CPUs: Cortex-A12, Cortex-A17, - Cortex-A7, Cortex-A5, Cortex-A9, Cortex-A15. - - - Added support in QEMU for Armv7-A/Cortex-A15. - -- Enhancements to Firmware Update feature: - - - Updated the FWU documentation to describe the additional images needed for - Firmware update, and how they are used for both the Juno platform and the - Arm FVP platforms. - -- Enhancements to Trusted Board Boot feature: - - - Added support to cert_create tool for RSA PKCS1# v1.5 and SHA384, SHA512 - and SHA256. - - - For Arm platforms added support to use ECDSA keys. - - - Enhanced the mbed TLS wrapper layer to include support for both RSA and - ECDSA to enable runtime selection between RSA and ECDSA keys. - -- Added support for secure interrupt handling in AArch32 sp_min, hardcoded to - only handle FIQs. - -- Added support to allow a platform to load images from multiple boot sources, - for example from a second flash drive. - -- Added a logging framework that allows platforms to reduce the logging level - at runtime and additionally the prefix string can be defined by the platform. - -- Further improvements to register initialisation: - - - Control register PMCR_EL0 / PMCR is set to prohibit cycle counting in the - secure world. This register is added to the list of registers that are - saved and restored during world switch. - - - When EL3 is running in AArch32 execution state, the Non-secure version of - SCTLR is explicitly initialised during the warmboot flow rather than - relying on the hardware to set the correct reset values. - -- Enhanced support for Arm platforms: - - - Introduced driver for Shared-Data-Structure (SDS) framework which is used - for communication between SCP and the AP CPU, replacing Boot-Over_MHU - (BOM) protocol. - - The Juno platform is migrated to use SDS with the SCMI support added in - v1.3 and is set as default. - - The driver can be found in the plat/arm/css/drivers folder. - - - Improved memory usage by only mapping TSP memory region when the TSPD has - been included in the build. This reduces the memory footprint and avoids - unnecessary memory being mapped. - - - Updated support for multi-threading CPUs for FVP platforms - always check - the MT field in MPDIR and access the bit fields accordingly. - - - Support building for platforms that model DynamIQ configuration by - implementing all CPUs in a single cluster. - - - Improved nor flash driver, for instance clearing status registers before - sending commands. Driver can be found plat/arm/board/common folder. - -- Enhancements to QEMU platform: - - - Added support for TBB. - - - Added support for using OP-TEE pageable image. - - - Added support for LOAD_IMAGE_V2. - - - Migrated to use translation table library v2 by default. - - - Added support for SEPARATE_CODE_AND_RODATA. - -- Applied workarounds CVE-2017-5715 on Arm Cortex-A57, -A72, -A73 and -A75, and - for Armv7-A CPUs Cortex-A9, -A15 and -A17. - -- Applied errata workaround for Arm Cortex-A57: 859972. - -- Applied errata workaround for Arm Cortex-A72: 859971. - -- Added support for Poplar 96Board platform. - -- Added support for Raspberry Pi 3 platform. - -- Added Call Frame Information (CFI) assembler directives to the vector entries - which enables debuggers to display the backtrace of functions that triggered - a synchronous abort. - -- Added ability to build dtb. - -- Added support for pre-tool (cert_create and fiptool) image processing - enabling compression of the image files before processing by cert_create and - fiptool. - - This can reduce fip size and may also speed up loading of images. The image - verification will also get faster because certificates are generated based on - compressed images. - - Imported zlib 1.2.11 to implement gunzip() for data compression. - -- Enhancements to fiptool: - - - Enabled the fiptool to be built using Visual Studio. - - - Added padding bytes at the end of the last image in the fip to be - facilitate transfer by DMA. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- TF-A can be built with optimisations disabled (-O0). - -- Memory layout updated to enable Trusted Board Boot on Juno platform when - running TF-A in AArch32 execution mode (resolving `tf-issue#501`_). - -Known Issues -^^^^^^^^^^^^ - -- DTB creation not supported when building on a Windows host. This step in the - build process is skipped when running on a Windows host. - -Version 1.4 ------------ - -New features -^^^^^^^^^^^^ - -- Enabled support for platforms with hardware assisted coherency. - - A new build option HW_ASSISTED_COHERENCY allows platforms to take advantage - of the following optimisations: - - - Skip performing cache maintenance during power-up and power-down. - - - Use spin-locks instead of bakery locks. - - - Enable data caches early on warm-booted CPUs. - -- Added support for Cortex-A75 and Cortex-A55 processors. - - Both Cortex-A75 and Cortex-A55 processors use the Arm DynamIQ Shared Unit - (DSU). The power-down and power-up sequences are therefore mostly managed in - hardware, reducing complexity of the software operations. - -- Introduced Arm GIC-600 driver. - - Arm GIC-600 IP complies with Arm GICv3 architecture. For FVP platforms, the - GIC-600 driver is chosen when FVP_USE_GIC_DRIVER is set to FVP_GIC600. - -- Updated GICv3 support: - - - Introduced power management APIs for GICv3 Redistributor. These APIs - allow platforms to power down the Redistributor during CPU power on/off. - Requires the GICv3 implementations to have power management operations. - - Implemented the power management APIs for FVP. - - - GIC driver data is flushed by the primary CPU so that secondary CPU do - not read stale GIC data. - -- Added support for Arm System Control and Management Interface v1.0 (SCMI). - - The SCMI driver implements the power domain management and system power - management protocol of the SCMI specification (Arm DEN 0056ASCMI) for - communicating with any compliant power controller. - - Support is added for the Juno platform. The driver can be found in the - plat/arm/css/drivers folder. - -- Added support to enable pre-integration of TBB with the Arm TrustZone - CryptoCell product, to take advantage of its hardware Root of Trust and - crypto acceleration services. - -- Enabled Statistical Profiling Extensions for lower ELs. - - The firmware support is limited to the use of SPE in the Non-secure state - and accesses to the SPE specific registers from S-EL1 will trap to EL3. - - The SPE are architecturally specified for AArch64 only. - -- Code hygiene changes aligned with MISRA guidelines: - - - Fixed signed / unsigned comparison warnings in the translation table - library. - - - Added U(_x) macro and together with the existing ULL(_x) macro fixed - some of the signed-ness defects flagged by the MISRA scanner. - -- Enhancements to Firmware Update feature: - - - The FWU logic now checks for overlapping images to prevent execution of - unauthenticated arbitrary code. - - - Introduced new FWU_SMC_IMAGE_RESET SMC that changes the image loading - state machine to go from COPYING, COPIED or AUTHENTICATED states to - RESET state. Previously, this was only possible when the authentication - of an image failed or when the execution of the image finished. - - - Fixed integer overflow which addressed TFV-1: Malformed Firmware Update - SMC can result in copy of unexpectedly large data into secure memory. - -- Introduced support for Arm Compiler 6 and LLVM (clang). - - TF-A can now also be built with the Arm Compiler 6 or the clang compilers. - The assembler and linker must be provided by the GNU toolchain. - - Tested with Arm CC 6.7 and clang 3.9.x and 4.0.x. - -- Memory footprint improvements: - - - Introduced `tf_snprintf`, a reduced version of `snprintf` which has - support for a limited set of formats. - - The mbedtls driver is updated to optionally use `tf_snprintf` instead of - `snprintf`. - - - The `assert()` is updated to no longer print the function name, and - additional logging options are supported via an optional platform define - `PLAT_LOG_LEVEL_ASSERT`, which controls how verbose the assert output is. - -- Enhancements to TF-A support when running in AArch32 execution state: - - - Support booting SP_MIN and BL33 in AArch32 execution mode on Juno. Due to - hardware limitations, BL1 and BL2 boot in AArch64 state and there is - additional trampoline code to warm reset into SP_MIN in AArch32 execution - state. - - - Added support for Arm Cortex-A53/57/72 MPCore processors including the - errata workarounds that are already implemented for AArch64 execution - state. - - - For FVP platforms, added AArch32 Trusted Board Boot support, including the - Firmware Update feature. - -- Introduced Arm SiP service for use by Arm standard platforms. - - - Added new Arm SiP Service SMCs to enable the Non-secure world to read PMF - timestamps. - - Added PMF instrumentation points in TF-A in order to quantify the - overall time spent in the PSCI software implementation. - - - Added new Arm SiP service SMC to switch execution state. - - This allows the lower exception level to change its execution state from - AArch64 to AArch32, or vice verse, via a request to EL3. - -- Migrated to use SPDX[0] license identifiers to make software license - auditing simpler. - - .. note:: - Files that have been imported by FreeBSD have not been modified. - - [0]: https://spdx.org/ - -- Enhancements to the translation table library: - - - Added version 2 of translation table library that allows different - translation tables to be modified by using different 'contexts'. Version 1 - of the translation table library only allows the current EL's translation - tables to be modified. - - Version 2 of the translation table also added support for dynamic - regions; regions that can be added and removed dynamically whilst the - MMU is enabled. Static regions can only be added or removed before the - MMU is enabled. - - The dynamic mapping functionality is enabled or disabled when compiling - by setting the build option PLAT_XLAT_TABLES_DYNAMIC to 1 or 0. This can - be done per-image. - - - Added support for translation regimes with two virtual address spaces - such as the one shared by EL1 and EL0. - - The library does not support initializing translation tables for EL0 - software. - - - Added support to mark the translation tables as non-cacheable using an - additional build option `XLAT_TABLE_NC`. - -- Added support for GCC stack protection. A new build option - ENABLE_STACK_PROTECTOR was introduced that enables compilation of all BL - images with one of the GCC -fstack-protector-* options. - - A new platform function plat_get_stack_protector_canary() was introduced - that returns a value used to initialize the canary for stack corruption - detection. For increased effectiveness of protection platforms must provide - an implementation that returns a random value. - -- Enhanced support for Arm platforms: - - - Added support for multi-threading CPUs, indicated by `MT` field in MPDIR. - A new build flag `ARM_PLAT_MT` is added, and when enabled, the functions - accessing MPIDR assume that the `MT` bit is set for the platform and - access the bit fields accordingly. - - Also, a new API `plat_arm_get_cpu_pe_count` is added when `ARM_PLAT_MT` is - enabled, returning the Processing Element count within the physical CPU - corresponding to `mpidr`. - - - The Arm platforms migrated to use version 2 of the translation tables. - - - Introduced a new Arm platform layer API `plat_arm_psci_override_pm_ops` - which allows Arm platforms to modify `plat_arm_psci_pm_ops` and therefore - dynamically define PSCI capability. - - - The Arm platforms migrated to use IMAGE_LOAD_V2 by default. - -- Enhanced reporting of errata workaround status with the following policy: - - - If an errata workaround is enabled: - - - If it applies (i.e. the CPU is affected by the errata), an INFO message - is printed, confirming that the errata workaround has been applied. - - - If it does not apply, a VERBOSE message is printed, confirming that the - errata workaround has been skipped. - - - If an errata workaround is not enabled, but would have applied had it - been, a WARN message is printed, alerting that errata workaround is - missing. - -- Added build options ARM_ARCH_MAJOR and ARM_ARM_MINOR to choose the - architecture version to target TF-A. - -- Updated the spin lock implementation to use the more efficient CAS (Compare - And Swap) instruction when available. This instruction was introduced in - Armv8.1-A. - -- Applied errata workaround for Arm Cortex-A53: 855873. - -- Applied errata workaround for Arm-Cortex-A57: 813419. - -- Enabled all A53 and A57 errata workarounds for Juno, both in AArch64 and - AArch32 execution states. - -- Added support for Socionext UniPhier SoC platform. - -- Added support for Hikey960 and Hikey platforms. - -- Added support for Rockchip RK3328 platform. - -- Added support for NVidia Tegra T186 platform. - -- Added support for Designware emmc driver. - -- Imported libfdt v1.4.2 that addresses buffer overflow in fdt_offset_ptr(). - -- Enhanced the CPU operations framework to allow power handlers to be - registered on per-level basis. This enables support for future CPUs that - have multiple threads which might need powering down individually. - -- Updated register initialisation to prevent unexpected behaviour: - - - Debug registers MDCR-EL3/SDCR and MDCR_EL2/HDCR are initialised to avoid - unexpected traps into the higher exception levels and disable secure - self-hosted debug. Additionally, secure privileged external debug on - Juno is disabled by programming the appropriate Juno SoC registers. - - - EL2 and EL3 configurable controls are initialised to avoid unexpected - traps in the higher exception levels. - - - Essential control registers are fully initialised on EL3 start-up, when - initialising the non-secure and secure context structures and when - preparing to leave EL3 for a lower EL. This gives better alignment with - the Arm ARM which states that software must initialise RES0 and RES1 - fields with 0 / 1. - -- Enhanced PSCI support: - - - Introduced new platform interfaces that decouple PSCI stat residency - calculation from PMF, enabling platforms to use alternative methods of - capturing timestamps. - - - PSCI stat accounting performed for retention/standby states when - requested at multiple power levels. - -- Simplified fiptool to have a single linked list of image descriptors. - -- For the TSP, resolved corruption of pre-empted secure context by aborting any - pre-empted SMC during PSCI power management requests. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- TF-A can be built with the latest mbed TLS version (v2.4.2). The earlier - version 2.3.0 cannot be used due to build warnings that the TF-A build - system interprets as errors. - -- TBBR, including the Firmware Update feature is now supported on FVP - platforms when running TF-A in AArch32 state. - -- The version of the AEMv8 Base FVP used in this release has resolved the issue - of the model executing a reset instead of terminating in response to a - shutdown request using the PSCI SYSTEM_OFF API. - -Known Issues -^^^^^^^^^^^^ - -- Building TF-A with compiler optimisations disabled (-O0) fails. - -- Trusted Board Boot currently does not work on Juno when running Trusted - Firmware in AArch32 execution state due to error when loading the sp_min to - memory because of lack of free space available. See `tf-issue#501`_ for more - details. - -- The errata workaround for A53 errata 843419 is only available from binutils - 2.26 and is not present in GCC4.9. If this errata is applicable to the - platform, please use GCC compiler version of at least 5.0. See `PR#1002`_ for - more details. - -Version 1.3 ------------ - - -New features -^^^^^^^^^^^^ - -- Added support for running TF-A in AArch32 execution state. - - The PSCI library has been refactored to allow integration with **EL3 Runtime - Software**. This is software that is executing at the highest secure - privilege which is EL3 in AArch64 or Secure SVC/Monitor mode in AArch32. See - :ref:`PSCI Library Integration guide for Armv8-A AArch32 systems`. - - Included is a minimal AArch32 Secure Payload, **SP-MIN**, that illustrates - the usage and integration of the PSCI library with EL3 Runtime Software - running in AArch32 state. - - Booting to the BL1/BL2 images as well as booting straight to the Secure - Payload is supported. - -- Improvements to the initialization framework for the PSCI service and Arm - Standard Services in general. - - The PSCI service is now initialized as part of Arm Standard Service - initialization. This consolidates the initializations of any Arm Standard - Service that may be added in the future. - - A new function ``get_arm_std_svc_args()`` is introduced to get arguments - corresponding to each standard service and must be implemented by the EL3 - Runtime Software. - - For PSCI, a new versioned structure ``psci_lib_args_t`` is introduced to - initialize the PSCI Library. **Note** this is a compatibility break due to - the change in the prototype of ``psci_setup()``. - -- To support AArch32 builds of BL1 and BL2, implemented a new, alternative - firmware image loading mechanism that adds flexibility. - - The current mechanism has a hard-coded set of images and execution order - (BL31, BL32, etc). The new mechanism is data-driven by a list of image - descriptors provided by the platform code. - - Arm platforms have been updated to support the new loading mechanism. - - The new mechanism is enabled by a build flag (``LOAD_IMAGE_V2``) which is - currently off by default for the AArch64 build. - - **Note** ``TRUSTED_BOARD_BOOT`` is currently not supported when - ``LOAD_IMAGE_V2`` is enabled. - -- Updated requirements for making contributions to TF-A. - - Commits now must have a 'Signed-off-by:' field to certify that the - contribution has been made under the terms of the - :download:`Developer Certificate of Origin <../dco.txt>`. - - A signed CLA is no longer required. - - The :ref:`Contributor's Guide` has been updated to reflect this change. - -- Introduced Performance Measurement Framework (PMF) which provides support - for capturing, storing, dumping and retrieving time-stamps to measure the - execution time of critical paths in the firmware. This relies on defining - fixed sample points at key places in the code. - -- To support the QEMU platform port, imported libfdt v1.4.1 from - https://git.kernel.org/pub/scm/utils/dtc/dtc.git - -- Updated PSCI support: - - - Added support for PSCI NODE_HW_STATE API for Arm platforms. - - - New optional platform hook, ``pwr_domain_pwr_down_wfi()``, in - ``plat_psci_ops`` to enable platforms to perform platform-specific actions - needed to enter powerdown, including the 'wfi' invocation. - - - PSCI STAT residency and count functions have been added on Arm platforms - by using PMF. - -- Enhancements to the translation table library: - - - Limited memory mapping support for region overlaps to only allow regions - to overlap that are identity mapped or have the same virtual to physical - address offset, and overlap completely but must not cover the same area. - - This limitation will enable future enhancements without having to - support complex edge cases that may not be necessary. - - - The initial translation lookup level is now inferred from the virtual - address space size. Previously, it was hard-coded. - - - Added support for mapping Normal, Inner Non-cacheable, Outer - Non-cacheable memory in the translation table library. - - This can be useful to map a non-cacheable memory region, such as a DMA - buffer. - - - Introduced the MT_EXECUTE/MT_EXECUTE_NEVER memory mapping attributes to - specify the access permissions for instruction execution of a memory - region. - -- Enabled support to isolate code and read-only data on separate memory pages, - allowing independent access control to be applied to each. - -- Enabled SCR_EL3.SIF (Secure Instruction Fetch) bit in BL1 and BL31 common - architectural setup code, preventing fetching instructions from non-secure - memory when in secure state. - -- Enhancements to FIP support: - - - Replaced ``fip_create`` with ``fiptool`` which provides a more consistent - and intuitive interface as well as additional support to remove an image - from a FIP file. - - - Enabled printing the SHA256 digest with info command, allowing quick - verification of an image within a FIP without having to extract the - image and running sha256sum on it. - - - Added support for unpacking the contents of an existing FIP file into - the working directory. - - - Aligned command line options for specifying images to use same naming - convention as specified by TBBR and already used in cert_create tool. - -- Refactored the TZC-400 driver to also support memory controllers that - integrate TZC functionality, for example Arm CoreLink DMC-500. Also added - DMC-500 specific support. - -- Implemented generic delay timer based on the system generic counter and - migrated all platforms to use it. - -- Enhanced support for Arm platforms: - - - Updated image loading support to make SCP images (SCP_BL2 and SCP_BL2U) - optional. - - - Enhanced topology description support to allow multi-cluster topology - definitions. - - - Added interconnect abstraction layer to help platform ports select the - right interconnect driver, CCI or CCN, for the platform. - - - Added support to allow loading BL31 in the TZC-secured DRAM instead of - the default secure SRAM. - - - Added support to use a System Security Control (SSC) Registers Unit - enabling TF-A to be compiled to support multiple Arm platforms and - then select one at runtime. - - - Restricted mapping of Trusted ROM in BL1 to what is actually needed by - BL1 rather than entire Trusted ROM region. - - - Flash is now mapped as execute-never by default. This increases security - by restricting the executable region to what is strictly needed. - -- Applied following erratum workarounds for Cortex-A57: 833471, 826977, - 829520, 828024 and 826974. - -- Added support for Mediatek MT6795 platform. - -- Added support for QEMU virtualization Armv8-A target. - -- Added support for Rockchip RK3368 and RK3399 platforms. - -- Added support for Xilinx Zynq UltraScale+ MPSoC platform. - -- Added support for Arm Cortex-A73 MPCore Processor. - -- Added support for Arm Cortex-A72 processor. - -- Added support for Arm Cortex-A35 processor. - -- Added support for Arm Cortex-A32 MPCore Processor. - -- Enabled preloaded BL33 alternative boot flow, in which BL2 does not load - BL33 from non-volatile storage and BL31 hands execution over to a preloaded - BL33. The User Guide has been updated with an example of how to use this - option with a bootwrapped kernel. - -- Added support to build TF-A on a Windows-based host machine. - -- Updated Trusted Board Boot prototype implementation: - - - Enabled the ability for a production ROM with TBBR enabled to boot test - software before a real ROTPK is deployed (e.g. manufacturing mode). - Added support to use ROTPK in certificate without verifying against the - platform value when ``ROTPK_NOT_DEPLOYED`` bit is set. - - - Added support for non-volatile counter authentication to the - Authentication Module to protect against roll-back. - -- Updated GICv3 support: - - - Enabled processor power-down and automatic power-on using GICv3. - - - Enabled G1S or G0 interrupts to be configured independently. - - - Changed FVP default interrupt driver to be the GICv3-only driver. - **Note** the default build of TF-A will not be able to boot - Linux kernel with GICv2 FDT blob. - - - Enabled wake-up from CPU_SUSPEND to stand-by by temporarily re-routing - interrupts and then restoring after resume. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Known issues -^^^^^^^^^^^^ - -- The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI ``SYSTEM_OFF`` API. This issue will be fixed in a future version of - the model. - -- Building TF-A with compiler optimisations disabled (``-O0``) fails. - -- TF-A cannot be built with mbed TLS version v2.3.0 due to build warnings - that the TF-A build system interprets as errors. - -- TBBR is not currently supported when running TF-A in AArch32 state. - -Version 1.2 ------------ - -New features -^^^^^^^^^^^^ - -- The Trusted Board Boot implementation on Arm platforms now conforms to the - mandatory requirements of the TBBR specification. - - In particular, the boot process is now guarded by a Trusted Watchdog, which - will reset the system in case of an authentication or loading error. On Arm - platforms, a secure instance of Arm SP805 is used as the Trusted Watchdog. - - Also, a firmware update process has been implemented. It enables - authenticated firmware to update firmware images from external interfaces to - SoC Non-Volatile memories. This feature functions even when the current - firmware in the system is corrupt or missing; it therefore may be used as - a recovery mode. - -- Improvements have been made to the Certificate Generation Tool - (``cert_create``) as follows. - - - Added support for the Firmware Update process by extending the Chain - of Trust definition in the tool to include the Firmware Update - certificate and the required extensions. - - - Introduced a new API that allows one to specify command line options in - the Chain of Trust description. This makes the declaration of the tool's - arguments more flexible and easier to extend. - - - The tool has been reworked to follow a data driven approach, which - makes it easier to maintain and extend. - -- Extended the FIP tool (``fip_create``) to support the new set of images - involved in the Firmware Update process. - -- Various memory footprint improvements. In particular: - - - The bakery lock structure for coherent memory has been optimised. - - - The mbed TLS SHA1 functions are not needed, as SHA256 is used to - generate the certificate signature. Therefore, they have been compiled - out, reducing the memory footprint of BL1 and BL2 by approximately - 6 KB. - - - On Arm development platforms, each BL stage now individually defines - the number of regions that it needs to map in the MMU. - -- Added the following new design documents: - - - :ref:`Authentication Framework & Chain of Trust` - - :ref:`Firmware Update (FWU)` - - :ref:`CPU Reset` - - :ref:`PSCI Power Domain Tree Structure` - -- Applied the new image terminology to the code base and documentation, as - described in the :ref:`Image Terminology` document. - -- The build system has been reworked to improve readability and facilitate - adding future extensions. - -- On Arm standard platforms, BL31 uses the boot console during cold boot - but switches to the runtime console for any later logs at runtime. The TSP - uses the runtime console for all output. - -- Implemented a basic NOR flash driver for Arm platforms. It programs the - device using CFI (Common Flash Interface) standard commands. - -- Implemented support for booting EL3 payloads on Arm platforms, which - reduces the complexity of developing EL3 baremetal code by doing essential - baremetal initialization. - -- Provided separate drivers for GICv3 and GICv2. These expect the entire - software stack to use either GICv2 or GICv3; hybrid GIC software systems - are no longer supported and the legacy Arm GIC driver has been deprecated. - -- Added support for Juno r1 and r2. A single set of Juno TF-A binaries can run - on Juno r0, r1 and r2 boards. Note that this TF-A version depends on a Linaro - release that does *not* contain Juno r2 support. - -- Added support for MediaTek mt8173 platform. - -- Implemented a generic driver for Arm CCN IP. - -- Major rework of the PSCI implementation. - - - Added framework to handle composite power states. - - - Decoupled the notions of affinity instances (which describes the - hierarchical arrangement of cores) and of power domain topology, instead - of assuming a one-to-one mapping. - - - Better alignment with version 1.0 of the PSCI specification. - -- Added support for the SYSTEM_SUSPEND PSCI API on Arm platforms. When invoked - on the last running core on a supported platform, this puts the system - into a low power mode with memory retention. - -- Unified the reset handling code as much as possible across BL stages. - Also introduced some build options to enable optimization of the reset path - on platforms that support it. - -- Added a simple delay timer API, as well as an SP804 timer driver, which is - enabled on FVP. - -- Added support for NVidia Tegra T210 and T132 SoCs. - -- Reorganised Arm platforms ports to greatly improve code shareability and - facilitate the reuse of some of this code by other platforms. - -- Added support for Arm Cortex-A72 processor in the CPU specific framework. - -- Provided better error handling. Platform ports can now define their own - error handling, for example to perform platform specific bookkeeping or - post-error actions. - -- Implemented a unified driver for Arm Cache Coherent Interconnects used for - both CCI-400 & CCI-500 IPs. Arm platforms ports have been migrated to this - common driver. The standalone CCI-400 driver has been deprecated. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- The Trusted Board Boot implementation has been redesigned to provide greater - modularity and scalability. See the - :ref:`Authentication Framework & Chain of Trust` document. - All missing mandatory features are now implemented. - -- The FVP and Juno ports may now use the hash of the ROTPK stored in the - Trusted Key Storage registers to verify the ROTPK. Alternatively, a - development public key hash embedded in the BL1 and BL2 binaries might be - used instead. The location of the ROTPK is chosen at build-time using the - ``ARM_ROTPK_LOCATION`` build option. - -- GICv3 is now fully supported and stable. - -Known issues -^^^^^^^^^^^^ - -- The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI ``SYSTEM_OFF`` API. This issue will be fixed in a future version of - the model. - -- While this version has low on-chip RAM requirements, there are further - RAM usage enhancements that could be made. - -- The upstream documentation could be improved for structural consistency, - clarity and completeness. In particular, the design documentation is - incomplete for PSCI, the TSP(D) and the Juno platform. - -- Building TF-A with compiler optimisations disabled (``-O0``) fails. - -Version 1.1 ------------ - -New features -^^^^^^^^^^^^ - -- A prototype implementation of Trusted Board Boot has been added. Boot - loader images are verified by BL1 and BL2 during the cold boot path. BL1 and - BL2 use the PolarSSL SSL library to verify certificates and images. The - OpenSSL library is used to create the X.509 certificates. Support has been - added to ``fip_create`` tool to package the certificates in a FIP. - -- Support for calling CPU and platform specific reset handlers upon entry into - BL3-1 during the cold and warm boot paths has been added. This happens after - another Boot ROM ``reset_handler()`` has already run. This enables a developer - to perform additional actions or undo actions already performed during the - first call of the reset handlers e.g. apply additional errata workarounds. - -- Support has been added to demonstrate routing of IRQs to EL3 instead of - S-EL1 when execution is in secure world. - -- The PSCI implementation now conforms to version 1.0 of the PSCI - specification. All the mandatory APIs and selected optional APIs are - supported. In particular, support for the ``PSCI_FEATURES`` API has been - added. A capability variable is constructed during initialization by - examining the ``plat_pm_ops`` and ``spd_pm_ops`` exported by the platform and - the Secure Payload Dispatcher. This is used by the PSCI FEATURES function - to determine which PSCI APIs are supported by the platform. - -- Improvements have been made to the PSCI code as follows. - - - The code has been refactored to remove redundant parameters from - internal functions. - - - Changes have been made to the code for PSCI ``CPU_SUSPEND``, ``CPU_ON`` and - ``CPU_OFF`` calls to facilitate an early return to the caller in case a - failure condition is detected. For example, a PSCI ``CPU_SUSPEND`` call - returns ``SUCCESS`` to the caller if a pending interrupt is detected early - in the code path. - - - Optional platform APIs have been added to validate the ``power_state`` and - ``entrypoint`` parameters early in PSCI ``CPU_ON`` and ``CPU_SUSPEND`` code - paths. - - - PSCI migrate APIs have been reworked to invoke the SPD hook to determine - the type of Trusted OS and the CPU it is resident on (if - applicable). Also, during a PSCI ``MIGRATE`` call, the SPD hook to migrate - the Trusted OS is invoked. - -- It is now possible to build TF-A without marking at least an extra page of - memory as coherent. The build flag ``USE_COHERENT_MEM`` can be used to - choose between the two implementations. This has been made possible through - these changes. - - - An implementation of Bakery locks, where the locks are not allocated in - coherent memory has been added. - - - Memory which was previously marked as coherent is now kept coherent - through the use of software cache maintenance operations. - - Approximately, 4K worth of memory is saved for each boot loader stage when - ``USE_COHERENT_MEM=0``. Enabling this option increases the latencies - associated with acquire and release of locks. It also requires changes to - the platform ports. - -- It is now possible to specify the name of the FIP at build time by defining - the ``FIP_NAME`` variable. - -- Issues with dependencies on the 'fiptool' makefile target have been - rectified. The ``fip_create`` tool is now rebuilt whenever its source files - change. - -- The BL3-1 runtime console is now also used as the crash console. The crash - console is changed to SoC UART0 (UART2) from the previous FPGA UART0 (UART0) - on Juno. In FVP, it is changed from UART0 to UART1. - -- CPU errata workarounds are applied only when the revision and part number - match. This behaviour has been made consistent across the debug and release - builds. The debug build additionally prints a warning if a mismatch is - detected. - -- It is now possible to issue cache maintenance operations by set/way for a - particular level of data cache. Levels 1-3 are currently supported. - -- The following improvements have been made to the FVP port. - - - The build option ``FVP_SHARED_DATA_LOCATION`` which allowed relocation of - shared data into the Trusted DRAM has been deprecated. Shared data is - now always located at the base of Trusted SRAM. - - - BL2 Translation tables have been updated to map only the region of - DRAM which is accessible to normal world. This is the region of the 2GB - DDR-DRAM memory at 0x80000000 excluding the top 16MB. The top 16MB is - accessible to only the secure world. - - - BL3-2 can now reside in the top 16MB of DRAM which is accessible only to - the secure world. This can be done by setting the build flag - ``FVP_TSP_RAM_LOCATION`` to the value ``dram``. - -- Separate translation tables are created for each boot loader image. The - ``IMAGE_BLx`` build options are used to do this. This allows each stage to - create mappings only for areas in the memory map that it needs. - -- A Secure Payload Dispatcher (OPTEED) for the OP-TEE Trusted OS has been - added. Details of using it with TF-A can be found in :ref:`OP-TEE Dispatcher` - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- The Juno port has been aligned with the FVP port as follows. - - - Support for reclaiming all BL1 RW memory and BL2 memory by overlaying - the BL3-1/BL3-2 NOBITS sections on top of them has been added to the - Juno port. - - - The top 16MB of the 2GB DDR-DRAM memory at 0x80000000 is configured - using the TZC-400 controller to be accessible only to the secure world. - - - The Arm GIC driver is used to configure the GIC-400 instead of using a - GIC driver private to the Juno port. - - - PSCI ``CPU_SUSPEND`` calls that target a standby state are now supported. - - - The TZC-400 driver is used to configure the controller instead of direct - accesses to the registers. - -- The Linux kernel version referred to in the user guide has DVFS and HMP - support enabled. - -- DS-5 v5.19 did not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in - CADI server mode. This issue is not seen with DS-5 v5.20 and Version 6.2 of - the Cortex-A57-A53 Base FVPs. - -Known issues -^^^^^^^^^^^^ - -- The Trusted Board Boot implementation is a prototype. There are issues with - the modularity and scalability of the design. Support for a Trusted - Watchdog, firmware update mechanism, recovery images and Trusted debug is - absent. These issues will be addressed in future releases. - -- The FVP and Juno ports do not use the hash of the ROTPK stored in the - Trusted Key Storage registers to verify the ROTPK in the - ``plat_match_rotpk()`` function. This prevents the correct establishment of - the Chain of Trust at the first step in the Trusted Board Boot process. - -- The version of the AEMv8 Base FVP used in this release resets the model - instead of terminating its execution in response to a shutdown request using - the PSCI ``SYSTEM_OFF`` API. This issue will be fixed in a future version of - the model. - -- GICv3 support is experimental. There are known issues with GICv3 - initialization in the TF-A. - -- While this version greatly reduces the on-chip RAM requirements, there are - further RAM usage enhancements that could be made. - -- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -- The Juno-specific firmware design documentation is incomplete. - -Version 1.0 ------------ - -New features -^^^^^^^^^^^^ - -- It is now possible to map higher physical addresses using non-flat virtual - to physical address mappings in the MMU setup. - -- Wider use is now made of the per-CPU data cache in BL3-1 to store: - - - Pointers to the non-secure and secure security state contexts. - - - A pointer to the CPU-specific operations. - - - A pointer to PSCI specific information (for example the current power - state). - - - A crash reporting buffer. - -- The following RAM usage improvements result in a BL3-1 RAM usage reduction - from 96KB to 56KB (for FVP with TSPD), and a total RAM usage reduction - across all images from 208KB to 88KB, compared to the previous release. - - - Removed the separate ``early_exception`` vectors from BL3-1 (2KB code size - saving). - - - Removed NSRAM from the FVP memory map, allowing the removal of one - (4KB) translation table. - - - Eliminated the internal ``psci_suspend_context`` array, saving 2KB. - - - Correctly dimensioned the PSCI ``aff_map_node`` array, saving 1.5KB in the - FVP port. - - - Removed calling CPU mpidr from the bakery lock API, saving 160 bytes. - - - Removed current CPU mpidr from PSCI common code, saving 160 bytes. - - - Inlined the mmio accessor functions, saving 360 bytes. - - - Fully reclaimed all BL1 RW memory and BL2 memory on the FVP port by - overlaying the BL3-1/BL3-2 NOBITS sections on top of these at runtime. - - - Made storing the FP register context optional, saving 0.5KB per context - (8KB on the FVP port, with TSPD enabled and running on 8 CPUs). - - - Implemented a leaner ``tf_printf()`` function, allowing the stack to be - greatly reduced. - - - Removed coherent stacks from the codebase. Stacks allocated in normal - memory are now used before and after the MMU is enabled. This saves 768 - bytes per CPU in BL3-1. - - - Reworked the crash reporting in BL3-1 to use less stack. - - - Optimized the EL3 register state stored in the ``cpu_context`` structure - so that registers that do not change during normal execution are - re-initialized each time during cold/warm boot, rather than restored - from memory. This saves about 1.2KB. - - - As a result of some of the above, reduced the runtime stack size in all - BL images. For BL3-1, this saves 1KB per CPU. - -- PSCI SMC handler improvements to correctly handle calls from secure states - and from AArch32. - -- CPU contexts are now initialized from the ``entry_point_info``. BL3-1 fully - determines the exception level to use for the non-trusted firmware (BL3-3) - based on the SPSR value provided by the BL2 platform code (or otherwise - provided to BL3-1). This allows platform code to directly run non-trusted - firmware payloads at either EL2 or EL1 without requiring an EL2 stub or OS - loader. - -- Code refactoring improvements: - - - Refactored ``fvp_config`` into a common platform header. - - - Refactored the fvp gic code to be a generic driver that no longer has an - explicit dependency on platform code. - - - Refactored the CCI-400 driver to not have dependency on platform code. - - - Simplified the IO driver so it's no longer necessary to call ``io_init()`` - and moved all the IO storage framework code to one place. - - - Simplified the interface the the TZC-400 driver. - - - Clarified the platform porting interface to the TSP. - - - Reworked the TSPD setup code to support the alternate BL3-2 - initialization flow where BL3-1 generic code hands control to BL3-2, - rather than expecting the TSPD to hand control directly to BL3-2. - - - Considerable rework to PSCI generic code to support CPU specific - operations. - -- Improved console log output, by: - - - Adding the concept of debug log levels. - - - Rationalizing the existing debug messages and adding new ones. - - - Printing out the version of each BL stage at runtime. - - - Adding support for printing console output from assembler code, - including when a crash occurs before the C runtime is initialized. - -- Moved up to the latest versions of the FVPs, toolchain, EDK2, kernel, Linaro - file system and DS-5. - -- On the FVP port, made the use of the Trusted DRAM region optional at build - time (off by default). Normal platforms will not have such a "ready-to-use" - DRAM area so it is not a good example to use it. - -- Added support for PSCI ``SYSTEM_OFF`` and ``SYSTEM_RESET`` APIs. - -- Added support for CPU specific reset sequences, power down sequences and - register dumping during crash reporting. The CPU specific reset sequences - include support for errata workarounds. - -- Merged the Juno port into the master branch. Added support for CPU hotplug - and CPU idle. Updated the user guide to describe how to build and run on the - Juno platform. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Removed the concept of top/bottom image loading. The image loader now - automatically detects the position of the image inside the current memory - layout and updates the layout to minimize fragmentation. This resolves the - image loader limitations of previously releases. There are currently no - plans to support dynamic image loading. - -- CPU idle now works on the publicized version of the Foundation FVP. - -- All known issues relating to the compiler version used have now been - resolved. This TF-A version uses Linaro toolchain 14.07 (based on GCC 4.9). - -Known issues -^^^^^^^^^^^^ - -- GICv3 support is experimental. The Linux kernel patches to support this are - not widely available. There are known issues with GICv3 initialization in - the TF-A. - -- While this version greatly reduces the on-chip RAM requirements, there are - further RAM usage enhancements that could be made. - -- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -- The Juno-specific firmware design documentation is incomplete. - -- Some recent enhancements to the FVP port have not yet been translated into - the Juno port. These will be tracked via the tf-issues project. - -- The Linux kernel version referred to in the user guide has DVFS and HMP - support disabled due to some known instabilities at the time of this - release. A future kernel version will re-enable these features. - -- DS-5 v5.19 does not detect Version 5.8 of the Cortex-A57-A53 Base FVPs in - CADI server mode. This is because the ```` reported by the FVP in - this version has changed. For example, for the Cortex-A57x4-A53x4 Base FVP, - the ```` reported by the FVP is ``FVP_Base_Cortex_A57x4_A53x4``, while - DS-5 expects it to be ``FVP_Base_A57x4_A53x4``. - - The temporary fix to this problem is to change the name of the FVP in - ``sw/debugger/configdb/Boards/ARM FVP/Base_A57x4_A53x4/cadi_config.xml``. - Change the following line: - - :: - - System Generator:FVP_Base_A57x4_A53x4 - - to - System Generator:FVP_Base_Cortex-A57x4_A53x4 - - A similar change can be made to the other Cortex-A57-A53 Base FVP variants. - -Version 0.4 ------------ - -New features -^^^^^^^^^^^^ - -- Makefile improvements: - - - Improved dependency checking when building. - - - Removed ``dump`` target (build now always produces dump files). - - - Enabled platform ports to optionally make use of parts of the Trusted - Firmware (e.g. BL3-1 only), rather than being forced to use all parts. - Also made the ``fip`` target optional. - - - Specified the full path to source files and removed use of the ``vpath`` - keyword. - -- Provided translation table library code for potential re-use by platforms - other than the FVPs. - -- Moved architectural timer setup to platform-specific code. - -- Added standby state support to PSCI cpu_suspend implementation. - -- SRAM usage improvements: - - - Started using the ``-ffunction-sections``, ``-fdata-sections`` and - ``--gc-sections`` compiler/linker options to remove unused code and data - from the images. Previously, all common functions were being built into - all binary images, whether or not they were actually used. - - - Placed all assembler functions in their own section to allow more unused - functions to be removed from images. - - - Updated BL1 and BL2 to use a single coherent stack each, rather than one - per CPU. - - - Changed variables that were unnecessarily declared and initialized as - non-const (i.e. in the .data section) so they are either uninitialized - (zero init) or const. - -- Moved the Test Secure-EL1 Payload (BL3-2) to execute in Trusted SRAM by - default. The option for it to run in Trusted DRAM remains. - -- Implemented a TrustZone Address Space Controller (TZC-400) driver. A - default configuration is provided for the Base FVPs. This means the model - parameter ``-C bp.secure_memory=1`` is now supported. - -- Started saving the PSCI cpu_suspend 'power_state' parameter prior to - suspending a CPU. This allows platforms that implement multiple power-down - states at the same affinity level to identify a specific state. - -- Refactored the entire codebase to reduce the amount of nesting in header - files and to make the use of system/user includes more consistent. Also - split platform.h to separate out the platform porting declarations from the - required platform porting definitions and the definitions/declarations - specific to the platform port. - -- Optimized the data cache clean/invalidate operations. - -- Improved the BL3-1 unhandled exception handling and reporting. Unhandled - exceptions now result in a dump of registers to the console. - -- Major rework to the handover interface between BL stages, in particular the - interface to BL3-1. The interface now conforms to a specification and is - more future proof. - -- Added support for optionally making the BL3-1 entrypoint a reset handler - (instead of BL1). This allows platforms with an alternative image loading - architecture to re-use BL3-1 with fewer modifications to generic code. - -- Reserved some DDR DRAM for secure use on FVP platforms to avoid future - compatibility problems with non-secure software. - -- Added support for secure interrupts targeting the Secure-EL1 Payload (SP) - (using GICv2 routing only). Demonstrated this working by adding an interrupt - target and supporting test code to the TSP. Also demonstrated non-secure - interrupt handling during TSP processing. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Now support use of the model parameter ``-C bp.secure_memory=1`` in the Base - FVPs (see **New features**). - -- Support for secure world interrupt handling now available (see **New - features**). - -- Made enough SRAM savings (see **New features**) to enable the Test Secure-EL1 - Payload (BL3-2) to execute in Trusted SRAM by default. - -- The tested filesystem used for this release (Linaro AArch64 OpenEmbedded - 14.04) now correctly reports progress in the console. - -- Improved the Makefile structure to make it easier to separate out parts of - the TF-A for re-use in platform ports. Also, improved target dependency - checking. - -Known issues -^^^^^^^^^^^^ - -- GICv3 support is experimental. The Linux kernel patches to support this are - not widely available. There are known issues with GICv3 initialization in - the TF-A. - -- Dynamic image loading is not available yet. The current image loader - implementation (used to load BL2 and all subsequent images) has some - limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead - to loading errors, even if the images should theoretically fit in memory. - -- TF-A still uses too much on-chip Trusted SRAM. A number of RAM usage - enhancements have been identified to rectify this situation. - -- CPU idle does not work on the advertised version of the Foundation FVP. - Some FVP fixes are required that are not available externally at the time - of writing. This can be worked around by disabling CPU idle in the Linux - kernel. - -- Various bugs in TF-A, UEFI and the Linux kernel have been observed when - using Linaro toolchain versions later than 13.11. Although most of these - have been fixed, some remain at the time of writing. These mainly seem to - relate to a subtle change in the way the compiler converts between 64-bit - and 32-bit values (e.g. during casting operations), which reveals - previously hidden bugs in client code. - -- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -Version 0.3 ------------ - -New features -^^^^^^^^^^^^ - -- Support for Foundation FVP Version 2.0 added. - The documented UEFI configuration disables some devices that are unavailable - in the Foundation FVP, including MMC and CLCD. The resultant UEFI binary can - be used on the AEMv8 and Cortex-A57-A53 Base FVPs, as well as the Foundation - FVP. - - .. note:: - The software will not work on Version 1.0 of the Foundation FVP. - -- Enabled third party contributions. Added a new contributing.md containing - instructions for how to contribute and updated copyright text in all files - to acknowledge contributors. - -- The PSCI CPU_SUSPEND API has been stabilised to the extent where it can be - used for entry into power down states with the following restrictions: - - - Entry into standby states is not supported. - - The API is only supported on the AEMv8 and Cortex-A57-A53 Base FVPs. - -- The PSCI AFFINITY_INFO api has undergone limited testing on the Base FVPs to - allow experimental use. - -- Required C library and runtime header files are now included locally in - TF-A instead of depending on the toolchain standard include paths. The - local implementation has been cleaned up and reduced in scope. - -- Added I/O abstraction framework, primarily to allow generic code to load - images in a platform-independent way. The existing image loading code has - been reworked to use the new framework. Semi-hosting and NOR flash I/O - drivers are provided. - -- Introduced Firmware Image Package (FIP) handling code and tools. A FIP - combines multiple firmware images with a Table of Contents (ToC) into a - single binary image. The new FIP driver is another type of I/O driver. The - Makefile builds a FIP by default and the FVP platform code expect to load a - FIP from NOR flash, although some support for image loading using semi- - hosting is retained. - - .. note:: - Building a FIP by default is a non-backwards-compatible change. - - .. note:: - Generic BL2 code now loads a BL3-3 (non-trusted firmware) image into - DRAM instead of expecting this to be pre-loaded at known location. This is - also a non-backwards-compatible change. - - .. note:: - Some non-trusted firmware (e.g. UEFI) will need to be rebuilt so that - it knows the new location to execute from and no longer needs to copy - particular code modules to DRAM itself. - -- Reworked BL2 to BL3-1 handover interface. A new composite structure - (bl31_args) holds the superset of information that needs to be passed from - BL2 to BL3-1, including information on how handover execution control to - BL3-2 (if present) and BL3-3 (non-trusted firmware). - -- Added library support for CPU context management, allowing the saving and - restoring of - - - Shared system registers between Secure-EL1 and EL1. - - VFP registers. - - Essential EL3 system registers. - -- Added a framework for implementing EL3 runtime services. Reworked the PSCI - implementation to be one such runtime service. - -- Reworked the exception handling logic, making use of both SP_EL0 and SP_EL3 - stack pointers for determining the type of exception, managing general - purpose and system register context on exception entry/exit, and handling - SMCs. SMCs are directed to the correct EL3 runtime service. - -- Added support for a Test Secure-EL1 Payload (TSP) and a corresponding - Dispatcher (TSPD), which is loaded as an EL3 runtime service. The TSPD - implements Secure Monitor functionality such as world switching and - EL1 context management, and is responsible for communication with the TSP. - - .. note:: - The TSPD does not yet contain support for secure world interrupts. - .. note:: - The TSP/TSPD is not built by default. - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Support has been added for switching context between secure and normal - worlds in EL3. - -- PSCI API calls ``AFFINITY_INFO`` & ``PSCI_VERSION`` have now been tested (to - a limited extent). - -- The TF-A build artifacts are now placed in the ``./build`` directory and - sub-directories instead of being placed in the root of the project. - -- TF-A is now free from build warnings. Build warnings are now treated as - errors. - -- TF-A now provides C library support locally within the project to maintain - compatibility between toolchains/systems. - -- The PSCI locking code has been reworked so it no longer takes locks in an - incorrect sequence. - -- The RAM-disk method of loading a Linux file-system has been confirmed to - work with the TF-A and Linux kernel version (based on version 3.13) used - in this release, for both Foundation and Base FVPs. - -Known issues -^^^^^^^^^^^^ - -The following is a list of issues which are expected to be fixed in the future -releases of TF-A. - -- The TrustZone Address Space Controller (TZC-400) is not being programmed - yet. Use of model parameter ``-C bp.secure_memory=1`` is not supported. - -- No support yet for secure world interrupt handling. - -- GICv3 support is experimental. The Linux kernel patches to support this are - not widely available. There are known issues with GICv3 initialization in - TF-A. - -- Dynamic image loading is not available yet. The current image loader - implementation (used to load BL2 and all subsequent images) has some - limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead - to loading errors, even if the images should theoretically fit in memory. - -- TF-A uses too much on-chip Trusted SRAM. Currently the Test Secure-EL1 - Payload (BL3-2) executes in Trusted DRAM since there is not enough SRAM. - A number of RAM usage enhancements have been identified to rectify this - situation. - -- CPU idle does not work on the advertised version of the Foundation FVP. - Some FVP fixes are required that are not available externally at the time - of writing. - -- Various bugs in TF-A, UEFI and the Linux kernel have been observed when - using Linaro toolchain versions later than 13.11. Although most of these - have been fixed, some remain at the time of writing. These mainly seem to - relate to a subtle change in the way the compiler converts between 64-bit - and 32-bit values (e.g. during casting operations), which reveals - previously hidden bugs in client code. - -- The tested filesystem used for this release (Linaro AArch64 OpenEmbedded - 14.01) does not report progress correctly in the console. It only seems to - produce error output, not standard output. It otherwise appears to function - correctly. Other filesystem versions on the same software stack do not - exhibit the problem. - -- The Makefile structure doesn't make it easy to separate out parts of the - TF-A for re-use in platform ports, for example if only BL3-1 is required in - a platform port. Also, dependency checking in the Makefile is flawed. - -- The firmware design documentation for the Test Secure-EL1 Payload (TSP) and - its dispatcher (TSPD) is incomplete. Similarly for the PSCI section. - -Version 0.2 ------------ - -New features -^^^^^^^^^^^^ - -- First source release. - -- Code for the PSCI suspend feature is supplied, although this is not enabled - by default since there are known issues (see below). - -Issues resolved since last release -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- The "psci" nodes in the FDTs provided in this release now fully comply - with the recommendations made in the PSCI specification. - -Known issues -^^^^^^^^^^^^ - -The following is a list of issues which are expected to be fixed in the future -releases of TF-A. - -- The TrustZone Address Space Controller (TZC-400) is not being programmed - yet. Use of model parameter ``-C bp.secure_memory=1`` is not supported. - -- No support yet for secure world interrupt handling or for switching context - between secure and normal worlds in EL3. - -- GICv3 support is experimental. The Linux kernel patches to support this are - not widely available. There are known issues with GICv3 initialization in - TF-A. - -- Dynamic image loading is not available yet. The current image loader - implementation (used to load BL2 and all subsequent images) has some - limitations. Changing BL2 or BL3-1 load addresses in certain ways can lead - to loading errors, even if the images should theoretically fit in memory. - -- Although support for PSCI ``CPU_SUSPEND`` is present, it is not yet stable - and ready for use. - -- PSCI API calls ``AFFINITY_INFO`` & ``PSCI_VERSION`` are implemented but have - not been tested. - -- The TF-A make files result in all build artifacts being placed in the root - of the project. These should be placed in appropriate sub-directories. - -- The compilation of TF-A is not free from compilation warnings. Some of these - warnings have not been investigated yet so they could mask real bugs. - -- TF-A currently uses toolchain/system include files like stdio.h. It should - provide versions of these within the project to maintain compatibility - between toolchains/systems. - -- The PSCI code takes some locks in an incorrect sequence. This may cause - problems with suspend and hotplug in certain conditions. - -- The Linux kernel used in this release is based on version 3.12-rc4. Using - this kernel with the TF-A fails to start the file-system as a RAM-disk. It - fails to execute user-space ``init`` from the RAM-disk. As an alternative, - the VirtioBlock mechanism can be used to provide a file-system to the - kernel. - --------------- - -*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* - -.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf -.. _tf-issue#501: https://github.com/ARM-software/tf-issues/issues/501 -.. _PR#1002: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193 -.. _mbed TLS releases: https://tls.mbed.org/tech-updates/releases diff --git a/package-lock.json b/package-lock.json index 64e551337..1d95ac924 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@commitlint/cli": "^14.1.0", "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", + "conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a", "cz-conventional-changelog": "^3.3.0", "husky": "^7.0.4", "standard-version": "^9.3.2" @@ -1075,6 +1076,10 @@ "node": ">=10" } }, + "node_modules/conventional-changelog-tf-a": { + "resolved": "tools/conventional-changelog-tf-a", + "link": true + }, "node_modules/conventional-changelog-writer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", @@ -3813,6 +3818,16 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "tools/conventional-changelog-tf-a": { + "version": "1.0.0", + "dev": true, + "dependencies": { + "conventional-changelog-conventionalcommits": "^4.6.1", + "execa": "^5.1.1", + "lodash": "^4.17.21", + "q": "^1.5.1" + } } }, "dependencies": { @@ -4663,6 +4678,15 @@ "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true }, + "conventional-changelog-tf-a": { + "version": "file:tools/conventional-changelog-tf-a", + "requires": { + "conventional-changelog-conventionalcommits": "^4.6.1", + "execa": "^5.1.1", + "lodash": "^4.17.21", + "q": "^1.5.1" + } + }, "conventional-changelog-writer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz", diff --git a/package.json b/package.json index 0a284a8f6..50053c6a7 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,14 @@ "license": "BSD-3-Clause", "private": true, "scripts": { - "postinstall": "husky install" + "postinstall": "husky install", + "release": "standard-version -i docs/change-log.md" }, "devDependencies": { "@commitlint/cli": "^14.1.0", "@commitlint/config-conventional": "^14.1.0", "commitizen": "^4.2.4", + "conventional-changelog-tf-a": "file:tools/conventional-changelog-tf-a", "cz-conventional-changelog": "^3.3.0", "husky": "^7.0.4", "standard-version": "^9.3.2" diff --git a/tools/conventional-changelog-tf-a/index.js b/tools/conventional-changelog-tf-a/index.js new file mode 100644 index 000000000..2a9d5b4d8 --- /dev/null +++ b/tools/conventional-changelog-tf-a/index.js @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* eslint-env es6 */ + +"use strict"; + +const Handlebars = require("handlebars"); +const Q = require("q"); +const _ = require("lodash"); + +const ccConventionalChangelog = require("conventional-changelog-conventionalcommits/conventional-changelog"); +const ccParserOpts = require("conventional-changelog-conventionalcommits/parser-opts"); +const ccRecommendedBumpOpts = require("conventional-changelog-conventionalcommits/conventional-recommended-bump"); +const ccWriterOpts = require("conventional-changelog-conventionalcommits/writer-opts"); + +const execa = require("execa"); + +const readFileSync = require("fs").readFileSync; +const resolve = require("path").resolve; + +/* + * Register a Handlebars helper that lets us generate Markdown lists that can support multi-line + * strings. This is driven by inconsistent formatting of breaking changes, which may be multiple + * lines long and can terminate the list early unintentionally. + */ +Handlebars.registerHelper("tf-a-mdlist", function (indent, options) { + const spaces = new Array(indent + 1).join(" "); + const first = spaces + "- "; + const nth = spaces + " "; + + return first + options.fn(this).replace(/\n(?!\s*\n)/gm, `\n${nth}`).trim() + "\n"; +}); + +/* + * Register a Handlebars helper that concatenates multiple variables. We use this to generate the + * title for the section partials. + */ +Handlebars.registerHelper("tf-a-concat", function () { + let argv = Array.prototype.slice.call(arguments, 0); + + argv.pop(); + + return argv.join(""); +}); + +function writerOpts(config) { + /* + * Flatten the configuration's sections list. This helps us iterate over all of the sections + * when we don't care about the hierarchy. + */ + + const flattenSections = function (sections) { + return sections.flatMap(section => { + const subsections = flattenSections(section.sections || []); + + return [section].concat(subsections); + }) + }; + + const flattenedSections = flattenSections(config.sections); + + /* + * Register a helper to return a restructured version of the note groups that includes notes + * categorized by their section. + */ + Handlebars.registerHelper("tf-a-notes", function (noteGroups, options) { + const generateTemplateData = function (sections, notes) { + return (sections || []).flatMap(section => { + const templateData = { + title: section.title, + sections: generateTemplateData(section.sections, notes), + notes: notes.filter(note => section.scopes?.includes(note.commit.scope)), + }; + + /* + * Don't return a section if it contains no notes and no sub-sections. + */ + if ((templateData.sections.length == 0) && (templateData.notes.length == 0)) { + return []; + } + + return [templateData]; + }); + }; + + return noteGroups.map(noteGroup => { + return { + title: noteGroup.title, + sections: generateTemplateData(config.sections, noteGroup.notes), + notes: noteGroup.notes.filter(note => + !flattenedSections.some(section => section.scopes?.includes(note.commit.scope))), + }; + }); + }); + + /* + * Register a helper to return a restructured version of the commit groups that includes commits + * categorized by their section. + */ + Handlebars.registerHelper("tf-a-commits", function (commitGroups, options) { + const generateTemplateData = function (sections, commits) { + return (sections || []).flatMap(section => { + const templateData = { + title: section.title, + sections: generateTemplateData(section.sections, commits), + commits: commits.filter(commit => section.scopes?.includes(commit.scope)), + }; + + /* + * Don't return a section if it contains no notes and no sub-sections. + */ + if ((templateData.sections.length == 0) && (templateData.commits.length == 0)) { + return []; + } + + return [templateData]; + }); + }; + + return commitGroups.map(commitGroup => { + return { + title: commitGroup.title, + sections: generateTemplateData(config.sections, commitGroup.commits), + commits: commitGroup.commits.filter(commit => + !flattenedSections.some(section => section.scopes?.includes(commit.scope))), + }; + }); + }); + + const writerOpts = ccWriterOpts(config) + .then(writerOpts => { + const ccWriterOptsTransform = writerOpts.transform; + + /* + * These configuration properties can't be injected directly into the template because + * they themselves are templates. Instead, we register them as partials, which allows + * them to be evaluated as part of the templates they're used in. + */ + Handlebars.registerPartial("commitUrl", config.commitUrlFormat); + Handlebars.registerPartial("compareUrl", config.compareUrlFormat); + Handlebars.registerPartial("issueUrl", config.issueUrlFormat); + + /* + * Register the partials that allow us to recursively create changelog sections. + */ + + const notePartial = readFileSync(resolve(__dirname, "./templates/note.hbs"), "utf-8"); + const noteSectionPartial = readFileSync(resolve(__dirname, "./templates/note-section.hbs"), "utf-8"); + const commitSectionPartial = readFileSync(resolve(__dirname, "./templates/commit-section.hbs"), "utf-8"); + + Handlebars.registerPartial("tf-a-note", notePartial); + Handlebars.registerPartial("tf-a-note-section", noteSectionPartial); + Handlebars.registerPartial("tf-a-commit-section", commitSectionPartial); + + /* + * Override the base templates so that we can generate a changelog that looks at least + * similar to the pre-Conventional Commits TF-A changelog. + */ + writerOpts.mainTemplate = readFileSync(resolve(__dirname, "./templates/template.hbs"), "utf-8"); + writerOpts.headerPartial = readFileSync(resolve(__dirname, "./templates/header.hbs"), "utf-8"); + writerOpts.commitPartial = readFileSync(resolve(__dirname, "./templates/commit.hbs"), "utf-8"); + writerOpts.footerPartial = readFileSync(resolve(__dirname, "./templates/footer.hbs"), "utf-8"); + + writerOpts.transform = function (commit, context) { + /* + * Fix up commit trailers, which for some reason are not correctly recognized and + * end up showing up in the breaking changes. + */ + + commit.notes.forEach(note => { + const trailers = execa.sync("git", ["interpret-trailers", "--parse"], { + input: note.text + }).stdout; + + note.text = note.text.replace(trailers, "").trim(); + }); + + return ccWriterOptsTransform(commit, context); + }; + + return writerOpts; + }); + + return writerOpts; +} + +module.exports = function (parameter) { + const config = parameter || {}; + + return Q.all([ + ccConventionalChangelog(config), + ccParserOpts(config), + ccRecommendedBumpOpts(config), + writerOpts(config) + ]).spread(( + conventionalChangelog, + parserOpts, + recommendedBumpOpts, + writerOpts + ) => { + if (_.isFunction(parameter)) { + return parameter(null, { + gitRawCommitsOpts: { noMerges: null }, + conventionalChangelog, + parserOpts, + recommendedBumpOpts, + writerOpts + }); + } else { + return { + conventionalChangelog, + parserOpts, + recommendedBumpOpts, + writerOpts + }; + } + }); +}; diff --git a/tools/conventional-changelog-tf-a/package.json b/tools/conventional-changelog-tf-a/package.json new file mode 100644 index 000000000..3ad853d51 --- /dev/null +++ b/tools/conventional-changelog-tf-a/package.json @@ -0,0 +1,12 @@ +{ + "name": "conventional-changelog-tf-a", + "version": "1.0.0", + "private": true, + "main": "index.js", + "dependencies": { + "conventional-changelog-conventionalcommits": "^4.6.1", + "execa": "^5.1.1", + "lodash": "^4.17.21", + "q": "^1.5.1" + } +} diff --git a/tools/conventional-changelog-tf-a/templates/commit-section.hbs b/tools/conventional-changelog-tf-a/templates/commit-section.hbs new file mode 100644 index 000000000..86b33351a --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/commit-section.hbs @@ -0,0 +1,17 @@ +{{#if title ~}} +{{ header }} + +{{#if commits.length ~}} + {{#each commits ~}} + {{#tf-a-mdlist 0}}{{> commit root=@root showScope=../topLevel }}{{/tf-a-mdlist ~}} + {{/each}} + +{{/if ~}} + +{{#if sections.length ~}} + {{#each sections ~}} + {{#tf-a-mdlist 0}}{{> tf-a-commit-section root=@root header=(tf-a-concat "**" title "**") }}{{/tf-a-mdlist}} + {{/each}} +{{/if ~}} + +{{/if}} diff --git a/tools/conventional-changelog-tf-a/templates/commit.hbs b/tools/conventional-changelog-tf-a/templates/commit.hbs new file mode 100644 index 000000000..faf264a32 --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/commit.hbs @@ -0,0 +1,15 @@ +{{#if scope }} + {{~#if showScope }}**{{ scope }}:** {{/if}} +{{~/if}} + +{{~#if subject }} + {{~ subject }} +{{~else}} + {{~ header }} +{{~/if}} + +{{~#if hash }} {{#if @root.linkReferences ~}} + ([{{ shortHash }}]({{> commitUrl root=@root }})) +{{~else}} + {{~ shortHash }} +{{~/if}}{{~/if}} diff --git a/tools/conventional-changelog-tf-a/templates/footer.hbs b/tools/conventional-changelog-tf-a/templates/footer.hbs new file mode 100644 index 000000000..e69de29bb diff --git a/tools/conventional-changelog-tf-a/templates/header.hbs b/tools/conventional-changelog-tf-a/templates/header.hbs new file mode 100644 index 000000000..67cb297e0 --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/header.hbs @@ -0,0 +1,13 @@ +{{#if isPatch~}} + ### +{{~else~}} + ## +{{~/if}} {{#if @root.linkCompare~}} + [{{version}}]({{> compareUrl root=@root}}) +{{~else}} + {{~version}} +{{~/if}} +{{~#if title}} "{{title}}" +{{~/if}} +{{~#if date}} ({{date}}) +{{/if}} diff --git a/tools/conventional-changelog-tf-a/templates/note-section.hbs b/tools/conventional-changelog-tf-a/templates/note-section.hbs new file mode 100644 index 000000000..f501c9647 --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/note-section.hbs @@ -0,0 +1,13 @@ +{{ header }} + +{{#if notes.length ~}} + {{#each notes ~}} + {{#tf-a-mdlist 0}}{{> tf-a-note root=@root showScope=../topLevel }}{{/tf-a-mdlist}} + {{/each ~}} +{{/if ~}} + +{{#if sections.length ~}} + {{#each sections ~}} + {{#tf-a-mdlist 0}}{{> tf-a-note-section root=@root header=(tf-a-concat "**" title "**") }}{{/tf-a-mdlist}} + {{/each~}} +{{/if}} diff --git a/tools/conventional-changelog-tf-a/templates/note.hbs b/tools/conventional-changelog-tf-a/templates/note.hbs new file mode 100644 index 000000000..c780ee854 --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/note.hbs @@ -0,0 +1,3 @@ +{{ text }} + +**See:** {{#with commit }}{{> commit root=@root showScope=../showScope }}{{/with}} diff --git a/tools/conventional-changelog-tf-a/templates/template.hbs b/tools/conventional-changelog-tf-a/templates/template.hbs new file mode 100644 index 000000000..95fb68c4c --- /dev/null +++ b/tools/conventional-changelog-tf-a/templates/template.hbs @@ -0,0 +1,9 @@ +{{> header }} + +{{#each (tf-a-notes noteGroups) ~}} +{{> tf-a-note-section root=@root header=(tf-a-concat "### ⚠ " title) topLevel=true }} +{{/each ~}} + +{{#each (tf-a-commits commitGroups) ~}} +{{> tf-a-commit-section root=@root header=(tf-a-concat "### " title) topLevel=true }} +{{/each ~}} -- cgit v1.2.3 From 7d3b5193723ef1928a9108739b0193eecd962f22 Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Mon, 15 Nov 2021 10:50:30 +0000 Subject: docs(commit-style): add commit style documentation This change adds a new documentation page describing the commit style, acceptable Conventional Commits types and scopes, and documents the process for expanding the list of scopes. Change-Id: Iad957b67fa71a879e8aa0790c58a5b08cec300d6 Signed-off-by: Chris Kay --- docs/process/commit-style.rst | 163 ++++++++++++++++++++++++++++++++++++++++++ docs/process/contributing.rst | 53 +------------- docs/process/index.rst | 1 + 3 files changed, 166 insertions(+), 51 deletions(-) create mode 100644 docs/process/commit-style.rst diff --git a/docs/process/commit-style.rst b/docs/process/commit-style.rst new file mode 100644 index 000000000..e9df5cee5 --- /dev/null +++ b/docs/process/commit-style.rst @@ -0,0 +1,163 @@ +Commit Style +============ + +When writing commit messages, please think carefully about the purpose and scope +of the change you are making: describe briefly what the change does, and +describe in detail why it does it. This helps to ensure that changes to the +code-base are transparent and approachable to reviewers, and it allows us to +keep a more accurate changelog. You may use Markdown in commit messages. + +A good commit message provides all the background information needed for +reviewers to understand the intent and rationale of the patch. This information +is also useful for future reference. + +For example: + +- What does the patch do? +- What motivated it? +- What impact does it have? +- How was it tested? +- Have alternatives been considered? Why did you choose this approach over + another one? +- If it fixes an `issue`_, include a reference. + +|TF-A| follows the `Conventional Commits`_ specification. All commits to the +main repository are expected to adhere to these guidelines, so it is +**strongly** recommended that you read at least the `quick summary`_ of the +specification. + +To briefly summarize, commit messages are expected to be of the form: + +.. code:: + + [optional scope]: + + [optional body] + + [optional footer(s)] + +The following example commit message demonstrates the use of the +``refactor`` type and the ``amu`` scope: + +.. code:: + + refactor(amu): factor out register accesses + + This change introduces a small set of register getters and setters to + avoid having to repeatedly mask and shift in complex code. + + Change-Id: Ia372f60c5efb924cd6eeceb75112e635ad13d942 + Signed-off-by: Chris Kay + +The following `types` are permissible and are strictly enforced: + ++--------------+---------------------------------------------------------------+ +| Scope | Description | ++==============+===============================================================+ +| ``feat`` | A new feature | ++--------------+---------------------------------------------------------------+ +| ``fix`` | A bug fix | ++--------------+---------------------------------------------------------------+ +| ``build`` | Changes that affect the build system or external dependencies | ++--------------+---------------------------------------------------------------+ +| ``ci`` | Changes to our CI configuration files and scripts | ++--------------+---------------------------------------------------------------+ +| ``docs`` | Documentation-only changes | ++--------------+---------------------------------------------------------------+ +| ``perf`` | A code change that improves performance | ++--------------+---------------------------------------------------------------+ +| ``refactor`` | A code change that neither fixes a bug nor adds a feature | ++--------------+---------------------------------------------------------------+ +| ``revert`` | Changes that revert a previous change | ++--------------+---------------------------------------------------------------+ +| ``style`` | Changes that do not affect the meaning of the code | +| | (white-space, formatting, missing semi-colons, etc.) | ++--------------+---------------------------------------------------------------+ +| ``test`` | Adding missing tests or correcting existing tests | ++--------------+---------------------------------------------------------------+ +| ``chore`` | Any other change | ++--------------+---------------------------------------------------------------+ + +The permissible `scopes` are more flexible, and we maintain a list of them in +our :download:`Commitizen configuration file <../../.cz.json>`. Scopes in this +file are organized by their changelog section, each of which may have one or +more accepted scopes, but only the first of which is considered to be "blessed". +Scopes that are not blessed exist for changes submitted before scope enforcement +came into effect, and are considered deprecated. + +While we don't enforce scopes strictly, we do ask that commits use these if they +can, or add their own if no appropriate one exists (see :ref:`Adding Scopes`). + +It's highly recommended that you use the tooling installed by the optional steps +in the :ref:`prerequisites ` guide to validate commit messages +locally, as commitlint reports a live list of the acceptable scopes. + +.. _Adding Scopes: + +Adding Scopes +------------- + +Scopes that are either a) unblessed in the configuration file, or b) do not +exist in the configuration file at all are considered to be deprecated. If you +are adding a new component that does not yet have a designated scope, please +feel free to add one. + +For example, if you are adding or making modifications to `Foo`'s latest and +greatest new platform `Bar`, you would add it to the `Platforms` changelog +section, and the hierarchy should look something like this: + +.. code:: json + + { + "sections": [ + { + "title": "Platforms", + "sections": [ + { + "title": "Foo", + "scopes": ["foo"], + "sections": [ + { + "title": "Bar", + "scopes": ["bar"] + } + ] + } + ] + } + ] + } + +When creating new scopes, try to keep them short and succinct, and use kebab +case (``this-is-kebab-case``). Components with a product name (i.e. most +platforms and some drivers) should use that name (e.g. ``gic600ae``, +``flexspi``, ``stpmic1``), otherwise use a name that uniquely represents the +component (e.g. ``marvell-comphy-3700``, ``rcar3-drivers``, ``a3720-uart``). + +Mandated Trailers +----------------- + +Commits are expected to be signed off with the ``Signed-off-by:`` trailer using +your real name and email address. You can do this automatically by committing +with Git's ``-s`` flag. + +There may be multiple ``Signed-off-by:`` lines depending on the history of the +patch, but one **must** be the committer. More details may be found in the +`Gerrit Signed-off-by Lines guidelines`_. + +Ensure that each commit also has a unique ``Change-Id:`` line. If you have +followed optional steps in the prerequisites to either install the Node.js tools +or clone the repository using the "`Clone with commit-msg hook`" clone method, +then this should be done automatically for you. + +More details may be found in the `Gerrit Change-Ids documentation`_. + +-------------- + +*Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.* + +.. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0 +.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html +.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html +.. _issue: https://developer.trustedfirmware.org/project/board/1/ +.. _quick summary: https://www.conventionalcommits.org/en/v1.0.0/#summary diff --git a/docs/process/contributing.rst b/docs/process/contributing.rst index aa050dabe..d6f61d6c7 100644 --- a/docs/process/contributing.rst +++ b/docs/process/contributing.rst @@ -26,23 +26,11 @@ Getting Started Making Changes -------------- +- Ensure commits adhere to the the project's :ref:`Commit Style`. + - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project. -- Ensure your commit messages comply with the `Conventional Commits`_ - specification: - - .. code:: - - [optional scope]: - - [optional body] - - [optional footer(s)] - - You can use the tooling installed by the optional steps in the - :ref:`prerequisites ` guide to validate this locally. - - Keep the commits on topic. If you need to fix another bug or make another enhancement, please address it on a separate topic branch. @@ -52,39 +40,6 @@ Making Changes - Avoid long commit series. If you do have a long series, consider whether some commits should be squashed together or addressed in a separate topic. -- Ensure that each commit in the series has at least one ``Signed-off-by:`` - line, using your real name and email address. The names in the - ``Signed-off-by:`` and ``Commit:`` lines must match. By adding this line the - contributor certifies the contribution is made under the terms of the - :download:`Developer Certificate of Origin <../../dco.txt>`. - - There might be multiple ``Signed-off-by:`` lines, depending on the history - of the patch. - - More details may be found in the `Gerrit Signed-off-by Lines guidelines`_. - -- Ensure that each commit also has a unique ``Change-Id:`` line. If you have - cloned the repository with the "`Clone with commit-msg hook`" clone method - (following the :ref:`Prerequisites` document), this should already be the - case. - - More details may be found in the `Gerrit Change-Ids documentation`_. - -- Write informative and comprehensive commit messages. A good commit message - provides all the background information needed for reviewers to understand - the intent and rationale of the patch. This information is also useful for - future reference. - - For example: - - - What does the patch do? - - What motivated it? - - What impact does it have? - - How was it tested? - - Have alternatives been considered? Why did you choose this approach over - another one? - - If it fixes an `issue`_, include a reference. - - Follow the :ref:`Coding Style` and :ref:`Coding Guidelines`. - Use the checkpatch.pl script provided with the Linux source tree. A @@ -289,15 +244,11 @@ Binary Components *Copyright (c) 2013-2021, Arm Limited and Contributors. All rights reserved.* -.. _Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0 .. _developer.trustedfirmware.org: https://developer.trustedfirmware.org .. _review.trustedfirmware.org: https://review.trustedfirmware.org -.. _issue: https://developer.trustedfirmware.org/project/board/1/ .. _Trusted Firmware-A: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git .. _Git guidelines: http://git-scm.com/book/ch5-2.html .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html -.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html -.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html .. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io .. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries .. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst diff --git a/docs/process/index.rst b/docs/process/index.rst index 37324b0e9..bba2b40eb 100644 --- a/docs/process/index.rst +++ b/docs/process/index.rst @@ -8,6 +8,7 @@ Processes & Policies security platform-compatibility-policy + commit-style coding-style coding-guidelines contributing -- cgit v1.2.3 From 953910b06ab16b3c900fc98387bef92ceb6364cb Mon Sep 17 00:00:00 2001 From: Chris Kay Date: Fri, 12 Nov 2021 15:34:13 +0000 Subject: docs(changelog): categorize scopes This change makes a best-effort attempt to categorize the various Conventional Commits scopes that have been used over the past year into their relevant changelog sections. No scopes were formalized for the v2.5 release so it varies dramatically, but the output does not look totally awful. Nonetheless, it will need some manual tweaking. For every section with one or more potential scopes, the first scope represents the "blessed" scope. That is, the scope that new commits that belong to this category should use. Change-Id: I8b5594a62238c4f392dc71b187e73c3da988e443 Signed-off-by: Chris Kay --- .cz.json | 756 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 755 insertions(+), 1 deletion(-) diff --git a/.cz.json b/.cz.json index 97d485033..5447f1704 100644 --- a/.cz.json +++ b/.cz.json @@ -68,5 +68,759 @@ "hidden": true } ], - "sections": [] + "sections": [ + { + "title": "Architecture", + "sections": [ + { + "title": "Activity Monitors Extension (FEAT_AMU)", + "scopes": ["amu"] + }, + { + "title": "Support for the `HCRX_EL2` register (FEAT_HCX)", + "scopes": ["hcx"] + }, + { + "title": "Memory Partitioning and Monitoring (MPAM) Extension (FEAT_MPAM)", + "scopes": ["mpam"] + }, + { + "title": "Scalable Matrix Extension (FEAT_SME)", + "scopes": ["sme"] + }, + { + "title": "Scalable Vector Extension (FEAT_SVE)", + "scopes": ["sve"] + }, + { + "title": "Trace Buffer Extension (FEAT_TRBE)", + "scopes": ["trbe"] + }, + { + "title": "Self-hosted Trace Extensions (FEAT_TRF)", + "scopes": ["trf", "sys_reg_trace"] + } + ] + }, + { + "title": "Platforms", + "sections": [ + { + "title": "Allwinner", + "scopes": ["allwinner", "plat/allwinner"] + }, + { + "title": "Arm", + "scopes": ["arm", "plat/arm"], + "sections": [ + { + "title": "FPGA", + "scopes": ["fpga", "arm_fgpa", "arm_fpga", "plat/arm_fpga"] + }, + { + "title": "FVP", + "scopes": ["fvp", "plat/fvp"] + }, + { + "title": "FVP-R", + "scopes": ["fvp-r", "fvp_r"] + }, + { + "title": "Juno", + "scopes": ["juno"] + }, + { + "title": "Morello", + "scopes": ["morello"] + }, + { + "title": "RD", + "scopes": ["rd"], + "sections": [ + { + "title": "RD-N2", + "scopes": ["rdn2", "board/rdn2"] + } + ] + }, + { + "title": "SGI", + "scopes": ["sgi", "plat/sgi", "plat/arm/sgi" ] + }, + { + "title": "TC", + "scopes": ["tc"], + "sections": [ + { + "title": "TC0", + "scopes": ["tc0", "plat/tc0"] + } + ] + } + ] + }, + { + "title": "Marvell", + "scopes": ["marvell", "plat/marvell"], + "sections": [ + { + "title": "Armada", + "scopes": ["armada", "plat/marvell/armada"], + "sections": [ + { + "title": "A3K", + "scopes": ["a3k", "plat/marvell/a3k"] + }, + { + "title": "A8K", + "scopes": ["a8k", "plat/marvell/a8k"] + } + ] + } + ] + }, + { + "title": "MediaTek", + "scopes": ["mediatek", "plat/mediatek/common", "plat/mediatek"], + "sections": [ + { + "title": "MT8183", + "scopes": ["mt8183", "plat/mediatek/mt8183"] + }, + { + "title": "MT8192", + "scopes": ["mt8192", "plat/mdeiatek/mt8192"] + }, + { + "title": "MT8195", + "scopes": ["mt8195", "plat/mediatek/me8195", "plat/mediatek/mt8195", "plat/mdeiatek/mt8195"] + } + ] + }, + { + "title": "NVIDIA", + "scopes": ["nvidia"], + "sections": [ + { + "title": "Tegra", + "scopes": ["tegra", "plat/tegra"], + "sections": [ + { + "title": "Tegra 132", + "scopes": ["tegra132"] + } + ] + } + ] + }, + { + "title": "NXP", + "scopes": ["nxp", "plat/nxp", "plat/nxp/common"], + "sections": [ + { + "title": "i.MX", + "scopes": ["imx", "plat/imx", "plat/imx/imx"], + "sections": [ + { + "title": "i.MX 8M", + "scopes": ["imx8m", "plat/imx8m", "plat/imx/imx8m"], + "sections": [ + { + "title": "i.MX 8M Mini", + "scopes": ["imx8mm", "plat/imx/imx8m/imx8mm"] + }, + { + "title": "i.MX 8M Plus", + "scopes": ["imx8mp", "plat/imx/imx8m/imx8mp"] + } + ] + } + ] + }, + { + "title": "Layerscape", + "scopes": ["layerscape", "docs/nxp/layerscape"], + "sections": [ + { + "title": "LX2", + "scopes": ["lx2", "plat/nxp/lx2"], + "sections": [ + { + "title": "LX216", + "scopes": ["lx216", "plat/nxp/lx216x"], + "sections": [ + { + "title": "LX2160", + "scopes": ["lx2160", "plat/soc-lx2160"] + } + ] + }, + { + "title": "LS1028A", + "scopes": ["ls1028a", "plat/nxp/ls1028a"], + "sections": [ + { + "title": "LS1028ARDB", + "scopes": ["ls1028ardb", "plat/nxp/ls1028ardb"] + } + ] + } + ] + } + ] + } + ] + }, + { + "title": "QEMU", + "scopes": ["qemu", "plat/qemu"] + }, + { + "title": "QTI", + "scopes": ["qti"], + "sections": [ + { + "title": "SC1780", + "scopes": ["sc7180", "plat/qti/sc7180"] + }, + { + "title": "SC7280", + "scopes": ["sc7280", "plat/qti/sc7280"] + } + ] + }, + { + "title": "Raspberry Pi", + "scopes": ["rpi"], + "sections": [ + { + "title": "Raspberry Pi 4", + "scopes": ["rpi4"] + } + ] + }, + { + "title": "Renesas", + "scopes": ["renesas"], + "sections": [ + { + "title": "R-Car", + "scopes": ["rcar", "plat/rcar"], + "sections": [ + { + "title": "R-Car 3", + "scopes": ["rcar3", "plat/rcar3"] + } + ] + } + ] + }, + { + "title": "Rockchip", + "scopes": ["rockchip"], + "sections": [ + { + "title": "RK3399", + "scopes": ["rk3399", "rockchip/rk3399", "rk3399/suspend"] + } + ] + }, + { + "title": "Socionext", + "scopes": ["socionext"], + "sections": [ + { + "title": "Synquacer", + "scopes": ["synquacer", "plat/synquacer"] + } + ] + }, + { + "title": "ST", + "scopes": ["st", "plat/st"], + "sections": [ + { + "title": "ST32MP1", + "scopes": ["stm32mp1", "plat/st/stm32mp1"] + } + ] + }, + { + "title": "Xilinx", + "scopes": ["xilinx", "plat/xilinx"], + "sections": [ + { + "title": "Versal", + "scopes": ["versal", "plat/xilinx/versal/include", "plat/xilinx/versal", "plat/versal"] + }, + { + "title": "ZynqMP", + "scopes": ["zynqmp", "plat/zynqmp", "plat/xilinx/zynqmp"] + } + ] + } + ] + }, + { + "title": "Bootloader Images", + "scopes": ["bl", "bl_common"], + "sections": [ + { + "title": "BL1", + "scopes": ["bl1"] + }, + { + "title": "BL2", + "scopes": ["bl2"] + } + ] + }, + { + "title": "Services", + "scopes": ["services"], + "sections": [ + { + "title": "FF-A", + "scopes": ["ffa", "ff-a"] + }, + { + "title": "RME", + "scopes": ["rme"] + }, + { + "title": "SPM", + "scopes": ["spm", "spmc", "spmd", "SPMD", "spm_mm"] + } + ] + }, + { + "title": "Libraries", + "sections": [ + { + "title": "CPU Support", + "scopes": ["cpus", "cpu", "errata", "errata_report"] + }, + { + "title": "EL3 Runtime", + "scopes": ["el3-runtime", "el3_runtime"] + }, + { + "title": "FCONF", + "scopes": ["fconf"] + }, + { + "title": "MPMM", + "scopes": ["mpmm"] + }, + { + "title": "OP-TEE", + "scopes": ["optee", "lib/optee"] + }, + { + "title": "PSCI", + "scopes": ["psci"] + }, + { + "title": "GPT", + "scopes": ["gpt", "gpt_rme"] + }, + { + "title": "SMCCC", + "scopes": ["smccc"] + }, + { + "title": "Translation Tables", + "scopes": ["xlat"] + } + ] + }, + { + "title": "Drivers", + "sections": [ + { + "title": "Authentication", + "scopes": ["auth", "driver/auth"], + "sections": [ + { + "title": "CryptoCell-713", + "scopes": ["cc-713"] + } + ] + }, + { + "title": "FWU", + "scopes": ["fwu", "fwu_metadata"] + }, + { + "title": "I/O", + "scopes": ["io"], + "sections": [ + { + "title": "MTD", + "scopes": ["mtd", "io_mtd"] + } + ] + }, + { + "title": "Measured Boot", + "scopes": ["measured-boot", "measured boot", "measured_boot"] + }, + { + "title": "MMC", + "scopes": ["mmc", "drivers/mmc"] + }, + { + "title": "MTD", + "scopes": ["mtd", "drivers/mtd"], + "sections": [ + { + "title": "NAND", + "scopes": ["nand"], + "sections": [ + { + "title": "SPI NAND", + "scopes": ["spi-nand", "spi_nand"] + } + ] + } + ] + }, + { + "title": "SCMI", + "scopes": ["scmi", "scmi_common", "drivers/scmi-msg"] + }, + { + "title": "UFS", + "scopes": ["ufs"] + }, + { + "title": "Arm", + "scopes": ["arm-drivers"], + "sections": [ + { + "title": "Ethos-N", + "scopes": ["ethos-n", "drivers/arm/ethosn"] + }, + { + "title": "GIC", + "scopes": ["gic"], + "sections": [ + { + "title": "GICv3", + "scopes": ["gicv3"], + "sections": [ + { + "title": "GIC-600AE", + "scopes": ["gic600ae"] + } + ] + } + ] + }, + { + "title": "TZC", + "scopes": ["tzc"], + "sections": [ + { + "title": "TZC-400", + "scopes": ["tzc400", "drivers/tzc400"] + } + ] + } + ] + }, + { + "title": "Marvell", + "scopes": ["marvell-drivers"], + "sections": [ + { + "title": "COMPHY", + "scopes": ["marvell-comphy", "drivers/marvell/comphy"], + "sections": [ + { + "title": "Armada 3700", + "scopes": ["marvell-comphy-3700", "drivers/marvell/comphy-3700"] + }, + { + "title": "CP110", + "scopes": ["marvell-comphy-cp110", "drivers/marvell/comphy-cp110"] + } + ] + }, + { + "title": "UART", + "scopes": ["marvell-uart", "plat/marvell/uart"] + }, + { + "title": "Armada", + "scopes": ["armada-drivers"], + "sections": [ + { + "title": "A3K", + "scopes": ["a3k-drivers"], + "sections": [ + { + "title": "A3720", + "scopes": ["a3720-uart", "plat/marvell/a3720/uart"] + } + ] + } + ] + } + ] + }, + { + "title": "MediaTek", + "scopes": ["mediatek-drivers"], + "sections": [ + { + "title": "APU", + "scopes": ["mediatek-apu", "plat/mediatek/apu"] + }, + { + "title": "EMI MPU", + "scopes": ["mediatek-emi-mpu", "plat/mediatek/mpu"] + }, + { + "title": "PMIC Wrapper", + "scopes": ["mediatek-pmic-wrapper", "plat/mediatek/pmic_wrap"] + }, + { + "title": "MT8192", + "scopes": ["mt8192-drivers"], + "sections": [ + { + "title": "SPM", + "scopes": ["mt8192-spm", "mediatek/mt8192/spm"] + } + ] + } + ] + }, + { + "title": "NXP", + "scopes": ["nxp-drivers"], + "sections": [ + { + "title": "DCFG", + "scopes": ["nxp-dcfg", "driver/nxp/dcfg"] + }, + { + "title": "FLEXSPI", + "scopes": ["flexspi", "include/drivers/flexspi", "driver/nxp/xspi"] + }, + { + "title": "SCFG", + "scopes": ["nxp-scfg", "nxp/scfg"] + }, + { + "title": "SFP", + "scopes": ["nxp-sfp", "drivers/nxp/sfp"] + } + ] + }, + { + "title": "Renesas", + "scopes": ["renesas-drivers"], + "sections": [ + { + "title": "R-Car3", + "scopes": ["rcar3-drivers", "drivers/rcar3"] + } + ] + }, + { + "title": "ST", + "scopes": ["st-drivers", "drivers/st"], + "sections": [ + { + "title": "Clock", + "scopes": ["st-clock", "stm32mp_clk", "drivers/st/clk", "stm32mp1_clk"] + }, + { + "title": "I/O", + "scopes": ["st-io-drivers"], + "sections": [ + { + "title": "STM32 Image", + "scopes": ["st-io-stm32image", "io-stm32image", "io_stm32image"] + } + ] + }, + { + "title": "SDMMC2", + "scopes": ["st-sdmmc2", "stm32_sdmmc2"] + }, + { + "title": "ST PMIC", + "scopes": ["st-pmic", "drivers/st/pmic"] + }, + { + "title": "STPMIC1", + "scopes": ["stpmic1"] + }, + { + "title": "UART", + "scopes": ["st-uart"], + "sections": [ + { + "title": "STM32 Console", + "scopes": ["stm32-console", "stm32_console"] + } + ] + }, + { + "title": "USB", + "scopes": ["st-usb", "drivers/st/usb"] + } + ] + }, + { + "title": "USB", + "scopes": ["usb", "drivers/usb"] + } + ] + }, + { + "title": "Miscellaneous", + "sections": [ + { + "title": "AArch64", + "scopes": ["aarch64"] + }, + { + "title": "Debug", + "scopes": ["debug", "common/debug"] + }, + { + "title": "CRC32", + "scopes": ["crc32"], + "sections": [ + { + "title": "Hardware CRC32", + "scopes": ["hw-crc32", "hw_crc", "hw_crc32"] + }, + { + "title": "Software CRC32", + "scopes": ["sw-crc32", "sw_crc32"] + } + ] + }, + { + "title": "DT Bindings", + "scopes": ["dt-bindings"] + }, + { + "title": "FDT Wrappers", + "scopes": ["fdt-wrappers"] + }, + { + "title": "FDTs", + "scopes": ["fdts", "fdt"], + "sections": [ + { + "title": "Morello", + "scopes": ["morello-fdts", "fdts/morello"] + }, + { + "title": "STM32MP1", + "scopes": ["stm32mp1-fdts", "fdts stm32mp1"] + } + ] + }, + { + "title": "PIE", + "scopes": ["pie"] + }, + { + "title": "Security", + "scopes": ["security"] + }, + { + "title": "SDEI", + "scopes": ["sdei"] + }, + { + "title": "TBBR", + "scopes": ["tbbr"] + }, + { + "title": "NXP", + "sections": [ + { + "title": "OCRAM", + "scopes": ["nxp-ocram", "nxp/common/ocram"] + }, + { + "title": "PSCI", + "scopes": ["nxp-psci", "plat/nxp/common/psci"] + } + ] + } + ] + }, + { + "title": "Documentation", + "scopes": ["docs", "doc"], + "sections": [ + { + "title": "Changelog", + "scopes": ["changelog"] + }, + { + "title": "Commit Style", + "scopes": ["commit-style"] + }, + { + "title": "Contribution Guidelines", + "scopes": ["contributing", "contribution-guidelines", "docs-contributing.rst"] + }, + { + "title": "Maintainers", + "scopes": ["maintainers"] + }, + { + "title": "Prerequisites", + "scopes": ["prerequisites"] + } + ] + }, + { + "title": "Build System", + "scopes": ["build", "makefile", "Makefile"], + "sections": [ + { + "title": "Git Hooks", + "scopes": ["hooks"] + } + ] + }, + { + "title": "Tools", + "sections": [ + { + "title": "STM32 Image", + "scopes": ["stm32image", "tools/stm32image"] + } + ] + }, + { + "title": "Dependencies", + "scopes": ["deps"], + "sections": [ + { + "title": "checkpatch", + "scopes": ["checkpatch"] + }, + { + "title": "libfdt", + "scopes": ["libfdt"] + }, + { + "title": "Node Package Manager (NPM)", + "scopes": ["npm"] + } + ] + } + ] } -- cgit v1.2.3 From 7f322f228e76caa5480f827af0aa6751f00fc1c4 Mon Sep 17 00:00:00 2001 From: anzhou Date: Thu, 18 Nov 2021 19:18:13 +0800 Subject: fix(drivers/gic600ae_fmu): fix timeout calculation The previous codes were using the cntpct_el0 to check the time elapsed. But this physical timer does not seem to count for the expected time resulting in gic fmu communication failures on Tegra platforms. This patch uses the delay_timer instead to use a platform defined timer for calculating timeouts. Change-Id: Ic8646ad1662c9928ac64c4152deb27e8c86fe344 Signed-off-by: Anthony Zhou Signed-off-by: Varun Wadekar --- drivers/arm/gic/v3/gic600ae_fmu_helpers.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c index 84f72925c..4aa0efb32 100644 --- a/drivers/arm/gic/v3/gic600ae_fmu_helpers.c +++ b/drivers/arm/gic/v3/gic600ae_fmu_helpers.c @@ -46,17 +46,20 @@ /* Helper function to wait until FMU is ready to accept the next command */ static void wait_until_fmu_is_idle(uintptr_t base) { - uint64_t timeout_ref = timeout_init_us(GICFMU_IDLE_TIMEOUT_US); + uint32_t timeout_count = GICFMU_IDLE_TIMEOUT_US; uint64_t status; /* wait until status is 'busy' */ do { status = (gic_fmu_read_status(base) & BIT(0)); - if (timeout_elapsed(timeout_ref)) { + if (timeout_count-- == 0U) { ERROR("GIC600 AE FMU is not responding\n"); panic(); } + + udelay(1U); + } while (status == U(0)); } -- cgit v1.2.3 From 16c1c453263853908161a79cc4b27aa8c8f59e0f Mon Sep 17 00:00:00 2001 From: J-Alves Date: Mon, 4 Oct 2021 14:33:51 +0100 Subject: docs(ff-a): update documentation of FF-A interfaces - Overview of FF-A v1.1 notifications feature, and list of all the new related interface. - FFA_RXTX_UNMAP now implemented, so provided description. - FF-A v1.1 interfaces documented: FFA_SPM_ID_GET and FFA_SECONDARY_EP_REGISTER. Signed-off-by: J-Alves Change-Id: If40b4d2b2473f81ecfb2ddbf14852c3f10682867 --- docs/components/secure-partition-manager.rst | 162 +++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 8 deletions(-) diff --git a/docs/components/secure-partition-manager.rst b/docs/components/secure-partition-manager.rst index 057226181..8a0bae0f3 100644 --- a/docs/components/secure-partition-manager.rst +++ b/docs/components/secure-partition-manager.rst @@ -547,9 +547,8 @@ Primary core boot-up Upon boot-up, BL31 hands over to the SPMC (BL32) on the primary boot physical core. The SPMC performs its platform initializations and registers the SPMC secondary physical core entry point physical address by the use of the -FFA_SECONDARY_EP_REGISTER interface (SMC invocation from the SPMC to the SPMD -at secure physical FF-A instance). This interface is implementation-defined in -context of FF-A v1.0. +`FFA_SECONDARY_EP_REGISTER`_ interface (SMC invocation from the SPMC to the SPMD +at secure physical FF-A instance). The SPMC then creates secure partitions based on SP packages and manifests. Each secure partition is launched in sequence (`SP Boot order`_) on their "primary" @@ -593,6 +592,67 @@ a NWd FF-A driver has been loaded: Refer to `Power management`_ for further details. +Notifications +------------- + +The FF-A v1.1 specification `[1]`_ defines notifications as an asynchronous +communication mechanism with non-blocking semantics. It allows for one FF-A +endpoint to signal another for service provision, without hindering its current +progress. + +Hafnium currently supports 64 notifications. The IDs of each notification define +a position in a 64-bit bitmap. + +The signaling of notifications can interchangeably happen between NWd and SWd +FF-A endpoints. + +The SPMC is in charge of managing notifications from SPs to SPs, from SPs to +VMs, and from VMs to SPs. An hypervisor component would only manage +notifications from VMs to VMs. Given the SPMC has no visibility of the endpoints +deployed in NWd, the Hypervisor or OS kernel must invoke the interface +FFA_NOTIFICATION_BITMAP_CREATE to allocate the notifications bitmap per FF-A +endpoint in the NWd that supports it. + +A sender can signal notifications once the receiver has provided it with +permissions. Permissions are provided by invoking the interface +FFA_NOTIFICATION_BIND. + +Notifications are signaled by invoking FFA_NOTIFICATION_SET. Henceforth +they are considered to be in a pending sate. The receiver can retrieve its +pending notifications invoking FFA_NOTIFICATION_GET, which, from that moment, +are considered to be handled. + +Per the FF-A v1.1 spec, each FF-A endpoint must be associated with a scheduler +that is in charge of donating CPU cycles for notifications handling. The +FF-A driver calls FFA_NOTIFICATION_INFO_GET to retrieve the information about +which FF-A endpoints have pending notifications. The receiver scheduler is +called and informed by the FF-A driver, and it should allocate CPU cycles to the +receiver. + +There are two types of notifications supported: +- Global, which are targeted to a FF-A endpoint and can be handled within any of +its execution contexts, as determined by the scheduler of the system. +- Per-vCPU, which are targeted to a FF-A endpoint and to be handled within a +a specific execution context, as determined by the sender. + +The type of a notification is set when invoking FFA_NOTIFICATION_BIND to give +permissions to the sender. + +Notification signaling resorts to two interrupts: +- Schedule Receiver Interrupt: Non-secure physical interrupt to be handled by +the FF-A 'transport' driver within the receiver scheduler. At initialization +the SPMC (as suggested by the spec) configures a secure SGI, as non-secure, and +triggers it when there are pending notifications, and the respective receivers +need CPU cycles to handle them. +- Notifications Pending Interrupt: Virtual Interrupt to be handled by the +receiver of the notification. Set when there are pending notifications. For +per-vCPU the NPI is pended at the handling of FFA_NOTIFICATION_SET interface. + +The notifications receipt support is enabled in the partition FF-A manifest. + +The subsequent section provides more details about the each one of the +FF-A interfaces for notifications support. + Mandatory interfaces -------------------- @@ -602,7 +662,7 @@ The following interfaces are exposed to SPs: - ``FFA_FEATURES`` - ``FFA_RX_RELEASE`` - ``FFA_RXTX_MAP`` -- ``FFA_RXTX_UNMAP`` (not implemented) +- ``FFA_RXTX_UNMAP`` - ``FFA_PARTITION_INFO_GET`` - ``FFA_ID_GET`` - ``FFA_MSG_WAIT`` @@ -615,7 +675,18 @@ The following interfaces are exposed to SPs: - ``FFA_MEM_RETRIEVE_RESP`` - ``FFA_MEM_RELINQUISH`` - ``FFA_MEM_RECLAIM`` -- ``FFA_SECONDARY_EP_REGISTER`` + +As part of the support of FF-A v1.1, the following interfaces were added: + + - ``FFA_NOTIFICATION_BITMAP_CREATE`` + - ``FFA_NOTIFICATION_BITMAP_DESTROY`` + - ``FFA_NOTIFICATION_BIND`` + - ``FFA_NOTIFICATION_UNBIND`` + - ``FFA_NOTIFICATION_SET`` + - ``FFA_NOTIFICATION_GET`` + - ``FFA_NOTIFICATION_INFO_GET`` + - ``FFA_SPM_ID_GET`` + - ``FFA_SECONDARY_EP_REGISTER`` FFA_VERSION ~~~~~~~~~~~ @@ -651,9 +722,9 @@ When invoked from the Hypervisor or OS kernel, the buffers are mapped into the SPMC EL2 Stage-1 translation regime and marked as NS buffers in the MMU descriptors. -Note: - -- FFA_RXTX_UNMAP is not implemented. +The FFA_RXTX_UNMAP unmaps the RX/TX pair from the translation regime of the +caller, either it being the Hypervisor or OS kernel, as well as a secure +partition. FFA_PARTITION_INFO_GET ~~~~~~~~~~~~~~~~~~~~~~ @@ -719,6 +790,81 @@ and responses with the following rules: - An Hypervisor or OS kernel can send a direct request to an SP. - An SP can send a direct response to an Hypervisor or OS kernel. +FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The secure partitions notifications bitmap are statically allocated by the SPMC. +Hence, this interface is not to be issued by secure partitions. + +At initialization, the SPMC is not aware of VMs/partitions deployed in the +normal world. Hence, the Hypervisor or OS kernel must use both ABIs for SPMC +to be prepared to handle notifications for the provided VM ID. + +FFA_NOTIFICATION_BIND/FFA_NOTIFICATION_UNBIND +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pair of interfaces to manage permissions to signal notifications. Prior to +handling notifications, an FF-A endpoint must allow a given sender to signal a +bitmap of notifications. + +If the receiver doesn't have notification support enabled in its FF-A manifest, +it won't be able to bind notifications, hence forbidding it to receive any +notifications. + +FFA_NOTIFICATION_SET/FFA_NOTIFICATION_GET +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the notifications set are per-vCPU, the NPI interrupt is set as pending +for a given receiver partition. + +The FFA_NOTIFICATION_GET will retrieve all pending global notifications and all +pending per-vCPU notifications targeted to the current vCPU. + +Hafnium keeps the global counting of the pending notifications, which is +incremented and decremented at the handling of FFA_NOTIFICATION_SET and +FFA_NOTIFICATION_GET, respectively. If the counter reaches zero, prior to SPMC +triggering the SRI, it won't be triggered. + +FFA_NOTIFICATION_INFO_GET +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Hafnium keeps the global counting of pending notifications whose info has been +retrieved by this interface. The counting is incremented and decremented at the +handling of FFA_NOTIFICATION_INFO_GET and FFA_NOTIFICATION_GET, respectively. +It also tracks the notifications whose info has been retrieved individually, +such that it avoids duplicating returned information for subsequent calls to +FFA_NOTIFICATION_INFO_GET. For each notification, this state information is +reset when receiver called FFA_NOTIFICATION_GET to retrieve them. + +FFA_SPM_ID_GET +~~~~~~~~~~~~~~ + +Returns the FF-A ID allocated to the SPM component (which includes SPMC + SPMD). +At initialization, the SPMC queries the SPMD for the SPM ID, using this +same interface, and saves it. + +The call emitted at NS and secure physical FF-A instances returns the SPM ID +specified in the SPMC manifest. + +Secure partitions call this interface at the virtual instance, to which the SPMC +shall return the priorly retrieved SPM ID. + +The Hypervisor or OS kernel can issue an FFA_SPM_ID_GET call handled by the +SPMD, which returns the SPM ID. + +FFA_SECONDARY_EP_REGISTER +~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the SPMC boots, all secure partitions are initialized on their primary +Execution Context. + +The interface FFA_SECONDARY_EP_REGISTER is to be used by a secure partitions +from its first execution context, to provide the entry point address for +secondary execution contexts. + +A secondary EC is first resumed either upon invocation of PSCI_CPU_ON from +the NWd or by invocation of FFA_RUN. + SPMC-SPMD direct requests/responses ----------------------------------- -- cgit v1.2.3 From 63d2e96042295cacefe917f2dcd4d287388e0308 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Mon, 22 Nov 2021 22:33:39 +0000 Subject: docs(changelog): generate changelog For future reference, this changelog was generated with the following command: npm run release -- --skip.commit --skip.tag --release-as 2.6.0 Change-Id: Idf6be5c3be15ddfdb1d32fafb9e0e4b399b269f3 Signed-off-by: Chris Kay Signed-off-by: Manish V Badarkhe --- Makefile | 2 +- docs/change-log.md | 976 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 977 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 490529178..73007b413 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ # Trusted Firmware Version # VERSION_MAJOR := 2 -VERSION_MINOR := 5 +VERSION_MINOR := 6 # Default goal is build all images .DEFAULT_GOAL := all diff --git a/docs/change-log.md b/docs/change-log.md index 0d75dc561..f0cb35272 100644 --- a/docs/change-log.md +++ b/docs/change-log.md @@ -3,6 +3,982 @@ This document contains a summary of the new features, changes, fixes and known issues in each release of Trusted Firmware-A. +## 2.6 (2021-11-22) + +### ⚠ BREAKING CHANGES + +- **Architecture** + + - **Activity Monitors Extension (FEAT_AMU)** + + - The public AMU API has been reduced to enablement only + to facilitate refactoring work. These APIs were not previously used. + + **See:** privatize unused AMU APIs ([b4b726e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b4b726ea868359cf683c07337b69fe91a2a6929a)) + + - The `PLAT_AMU_GROUP1_COUNTERS_MASK` platform definition + has been removed. Platforms should specify per-core AMU counter masks + via FCONF or a platform-specific mechanism going forward. + + **See:** remove `PLAT_AMU_GROUP1_COUNTERS_MASK` ([6c8dda1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c8dda19e5f484f8544365fd71d965f0afc39244)) + +- **Libraries** + + - **FCONF** + + - FCONF is no longer added to BL1 and BL2 automatically + when the FCONF Makefile (`fconf.mk`) is included. When including this + Makefile, consider whether you need to add `${FCONF_SOURCES}` and + `${FCONF_DYN_SOURCES}` to `BL1_SOURCES` and `BL2_SOURCES`. + + **See:** clean up source collection ([e04da4c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e04da4c8e132f43218f18ad3b41479ca54bb9263)) + +- **Drivers** + + - **Arm** + + - **Ethos-N** + + - multi-device support + + **See:** multi-device support ([1c65989](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c65989e70c9734defc666e824628620b2060b92)) + +### New Features + +- **Architecture** + + - **Activity Monitors Extension (FEAT_AMU)** + + - enable per-core AMU auxiliary counters ([742ca23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/742ca2307f4e9f82cb2c21518819425e5bcc0f90)) + + - **Support for the `HCRX_EL2` register (FEAT_HCX)** + + - add build option to enable FEAT_HCX ([cb4ec47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cb4ec47b5c73e04472984acf821e6be41b98064f)) + + - **Scalable Matrix Extension (FEAT_SME)** + + - enable SME functionality ([dc78e62](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dc78e62d80e64bf4fe5d5bf4844a7bd1696b7c92)) + + - **Scalable Vector Extension (FEAT_SVE)** + + - enable SVE for the secure world ([0c5e7d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c5e7d1ce376cabcebebc43dbf238fe4482ab2dc)) + + - **Trace Buffer Extension (FEAT_TRBE)** + + - enable access to trace buffer control registers from lower NS EL ([813524e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/813524ea9d2e4138246b8f77a772299e52fb33bc)) + - initialize trap settings of trace buffer control registers access ([40ff907](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/40ff90747098ed9d2a09894d1a886c10ca76cee6)) + + - **Self-hosted Trace Extensions (FEAT_TRF)** + + - enable trace system registers access from lower NS ELs ([d4582d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d4582d30885673987240cf01fd4f5d2e6780e84c)) + - initialize trap settings of trace system registers access ([2031d61](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2031d6166a58623ae59034bc2353fcd2fabe9c30)) + - enable trace filter control register access from lower NS EL ([8fcd3d9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8fcd3d9600bb2cb6809c6fc68f945ce3ad89633d)) + - initialize trap settings of trace filter control registers access ([5de20ec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5de20ece38f782c8459f546a08c6a97b9e0f5bc5)) + + - **RME** + + - add context management changes for FEAT_RME ([c5ea4f8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c5ea4f8a6679131010636eb524d2a15b709d0196)) + - add ENABLE_RME build option and support for RMM image ([5b18de0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b18de09e80f87963df9a2e451c47e2321b8643a)) + - add GPT Library ([1839012](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1839012d5b5d431f7ec307230eae9890a5fe7477)) + - add Realm security state definition ([4693ff7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4693ff7225faadc5ad1bcd1c2fb3fbbb8fe1aed0)) + - add register definitions and helper functions for FEAT_RME ([81c272b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/81c272b3b71af38bc5cfb10bbe5722e328a1578e)) + - add RMM dispatcher (RMMD) ([77c2775](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77c2775323a5ff8b77230f05c0cc57f830e9f153)) + - add Test Realm Payload (TRP) ([50a3056](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/50a3056a3cd33d395e8712e1d1e67a8840bf3db1)) + - add xlat table library changes for FEAT_RME ([3621823](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/362182386bafbda9e6671be921fa30cc20610d30)) + - disable Watchdog for Arm platforms if FEAT_RME enabled ([07e96d1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/07e96d1d2958b6f121476fd391ac67bf8c2c4735)) + - run BL2 in root world when FEAT_RME is enabled ([6c09af9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c09af9f8b36cdfa1dc4d5052f7e4792f63fa88a)) + +- **Platforms** + + - **Allwinner** + + - add R329 support ([13bacd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13bacd3bc3e6b76009adf9183e5396b6457eb12c)) + + - **Arm** + + - add FWU support in Arm platforms ([2f1177b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2f1177b2b9ebec3b2fe92607cd771bda1dc9cbfc)) + - add GPT initialization code for Arm platforms ([deb4b3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/deb4b3a63e3a52f2e9823865a1932f6289ccb7ac)) + - add GPT parser support ([ef1daa4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef1daa420f7b2920b2ee35379de2aefed6ab2605)) + - enable PIE when RESET_TO_SP_MIN=1 ([7285fd5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7285fd5f9aa6d9cc0e0f1dc9c71785b46a88d999)) + + - **FPGA** + + - add ITS autodetection ([d7e39c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d7e39c43f2f58aabb085ed7b8f461f9ece6002d0)) + - add kernel trampoline ([de9fdb9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/de9fdb9b5925ae08137d4212a85e9a1d319509c9)) + - determine GICR base by probing ([93b785f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/93b785f5ae66a6418581c304c83a346e8baa5aa3)) + - query PL011 to learn system frequency ([d850169](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d850169c9c233c4bc413d8319196557b54683688)) + - support GICv4 images ([c69f815](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c69f815b09ab85d3ace8fd2979ffafb1184ec76c)) + - write UART baud base clock frequency into DTB ([422b44f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/422b44fb56db7ca8b1a2f9f706733d7d4c2fdeb1)) + + - **FVP** + + - enable external SP images in BL2 config ([33993a3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/33993a3737737a03ee5a9d386d0a027bdc947c9c)) + - add memory map for FVP platform for FEAT_RME ([c872072](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c8720729726faffc39ec64f3a02440a48c8c305a)) + - add RMM image support for FVP platform ([9d870b7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d870b79c16ef09b0c4a9db18e071c2fa235d1ad)) + - enable trace extension features by default ([cd3f0ae](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd3f0ae6f855b2998bc09e5c3a458528c92acb90)) + - pass Event Log addr and size from BL1 to BL2 ([0500f44](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0500f4479eb1d0d5ab9e83dac42b633a5ff677dd)) + + - **FVP-R** + + - support for TB-R has been added + - configure system registers to boot rich OS ([28bbbf3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28bbbf3bf583e0c85004727e694455dfcabd50a4)) + + - **RD** + + - **RD-N2** + + - add support for variant 1 of rd-n2 platform ([fe5d5bb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fe5d5bbfe6bd0f386f92bdc419a7e04d885d5b43)) + - add tzc master source ids for soc dma ([3139270](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3139270693ab0fc6d66fed4fe11e183829b47e2e)) + + - **SGI** + + - add CPU specific handler for Neoverse N2 ([d932a58](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d932a5831e26620d61d171d0fd8bc2f14938e6f1)) + - add CPU specific handler for Neoverse V1 ([cbee43e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cbee43ebd69377bce1c4fa8d40c6fd67f2be2ee4)) + - increase max BL2 size ([7186a29](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7186a29bbfe3044d5e8001ddfe1d9238578e0944)) + - enable AMU for RD-V1-MC ([e8b119e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8b119e03ad9de5fc440e5929287c94c22fc3946)) + - enable use of PSCI extended state ID format ([7bd64c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7bd64c70e91f73a236b84fb51d5045e308479b5a)) + - introduce platform variant build option ([cfe1506](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cfe1506ee8303d9e0714b3a5b2cd165f76ad5d11)) + + - **TC** + + - enable MPMM ([c19a82b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c19a82bef08df58350f1b6668e0604ff8a5bd46d)) + - Enable SVE for both secure and non-secure world ([10198ea](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10198eab3aa7b0eeba10d9667197816b052ba3e4)) + - populate HW_CONFIG in BL31 ([34a87d7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34a87d74d9fbbe8037431ea5101110a9f1cf30e1)) + - introduce TC1 platform ([6ec0c65](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6ec0c65b09745fd0f4cee44ee3aa99870303f448)) + - add DRAM2 to TZC non-secure region ([76b4a6b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/76b4a6bb208c22b1c5971964a209ff7d54982348)) + + - add bootargs node ([4a840f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4a840f27cd7a05d8e3687aa325adcd019c0d22ee)) + - add cpu capacity to provide scheduling information ([309f593](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/309f5938e610c73cb51b3ba175fed971f49d0888)) + - add Ivy partition ([a19bd32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a19bd32ed14c33571f3715198d47bac9d0f2808e)) + - add support for trusted services ([ca93248](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca9324819ee308f9b3a4bb004f02a512c8f301f6)) + - update Matterhorn ELP DVFS clock index ([a2f6294](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2f6294c98935895d4592ef7e30058ca6e995f4b)) + - update mhuv2 dts node to align with upstream driver ([63067ce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/63067ce87e4afa193b2c7f6a4917d1e54b61b000)) + + - **Diphda** + + - adding the diphda platform ([bf3ce99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf3ce9937182e5d8d91e058baabb8213acedacdb)) + - disabling non volatile counters in diphda ([7f70cd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f70cd29235cc5e96ff6b5f509c7e4260bec5610)) + - enabling stack protector for diphda ([c7e4f1c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c7e4f1cfb84136a7521f26e403a6635ffdce4a2b)) + + - **Marvell** + + - introduce t9130_cex7_eval ([d01139f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d01139f3b59a1bc6542e74f52ff3fb26eea23c69)) + + - **Armada** + + - **A8K** + + - allow overriding default paths ([0b702af](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0b702afc3aabc349a513a5b00397b58a62fea634)) + + - **MediaTek** + + - enable software reset for CIRQ ([b3b162f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3b162f3b48e087f6656513862a6f9e1fa0757b1)) + + - **MT8192** + + - add DFD control in SiP service ([5183e63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5183e637a0496ad8dfbd8c892bc874ac6a1531bf)) + + - **MT8195** + + - add DFD control in SiP service ([3b994a7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3b994a75306cc487144dd8e2e15433799e62e6f2)) + - add display port control in SiP service ([7eb4223](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7eb42237575eb3f241c9b22efc5fe91368470aa6)) + - remove adsp event from wakeup source ([c260b32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c260b3246b6be27c7463d36ce7f76368c94a8540)) + - add DCM driver ([49d3bd8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49d3bd8c4c80ecd19ecfd74812ff1eaa01478cdd)) + - add EMI MPU basic drivers ([75edd34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/75edd34ade8efaa8a76c5fd59103454023632989)) + - add SPM suspend driver ([859e346](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/859e346b89461f31df17b76ef25ce9e8d2a7279d)) + - add support for PTP3 ([0481896](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/048189637ead887787bd5bc47b1dfab98f321705)) + - add vcore-dvfs support ([d562130](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d562130ea9637b885135a5efe41cb98f2365754f)) + - support MCUSYS off when system suspend ([d336e09](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d336e093dd9ec917ce69484eae8914d98efa328d)) + + - **NXP** + + - add build macro for BOOT_MODE validation checking ([cd1280e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cd1280ea2e5c8be6f28485a2d5054d06e54e74c1)) + - add CCI and EPU address definition ([6cad59c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6cad59c429b4382ad62aee3a67fa1b3fd4ad38b7)) + - add EESR register definition ([8bfb168](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8bfb16813aff9b3dcbeaa2f77027d44b97f04b6d)) + - add SecMon register definition for ch_3_2 ([66f7884](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66f7884b5229b1d2977d73d105af1c34cb55f95d)) + - define common macro for ARM registers ([35efe7a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/35efe7a4cea4b3c55b661aac49ef1a85ca8feaa9)) + - define default PSCI features if not defined ([a204785](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2047853224083328ef67cacbc17a2001ba14701)) + - define default SD buffer ([4225ce8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4225ce8b87635287ecf5cd3baaf31ea703a2640b)) + + - **i.MX** + + - **i.MX 8M** + + - add sdei support for i.MX8MN ([ce2be32](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce2be321e8a5865871810b36c580181ea95a1a64)) + - add sdei support for i.MX8MP ([6b63125](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b63125c415491417e1c389e4015be5ebdee2841)) + - add SiP call for secondary boot ([9ce232f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ce232fe985a0bb308af459ede8a22629255d4e7)) + - add system_reset2 implementation ([60a0dde](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/60a0dde91bd03f4011c1d52d4d3aea8166e939a0)) + + - **i.MX 8M Mini** + + - enlarge BL33 (U-boot) size in FIP ([d53c9db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d53c9dbf9ff9c435552b62f47fb95bfe86d025e3)) + + - **i.MX 8M Plus** + + - add imx8mp_private.h to the build ([91566d6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/91566d663b26434813fa674412bb695be1965557)) + - add in BL2 with FIP ([75fbf55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/75fbf5546b7beca93e4782bc35906f9536392e04)) + - add initial definition to facilitate FIP layout ([f696843](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f696843eab5cf0547b6c6307eaccea25678654c4)) + - enable Trusted Boot ([a16ecd2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a16ecd2cff36b3a8a76d223f4e272e165c941b31)) + + - **Layerscape** + + - add ls1028a soc and board support ([52a1e9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/52a1e9ff37251987b71b743951038cd8d1fa0ba4)) + + - **LX2** + + - add SUPPORTED_BOOT_MODE definition ([28b3221](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/28b3221aebdd48577e2288a75cd2f7547da514e9)) + + - **LS1028A** + + - add ls1028a soc support ([9d250f0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d250f03d7a38cac86655495879b2151b877db0d)) + + - **LS1028ARDB** + + - add ls1028ardb board support ([34e2112](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34e2112d1a3a8e4ea33a24bdc6505518266333a9)) + + - **QTI** + + - **SC7280** + + - add support for pmk7325 ([b8a0511](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8a05116ed2a87a9689c4f9be6218a4bce88034a)) + - support for qti sc7280 plat ([46ee50e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/46ee50e0b34e19d383a28bc3b3dadbfb4c07b270)) + + - **Renesas** + + - **R-Car** + + - change process for Suspend To RAM ([731aa26](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/731aa26f38d76645b6d50077c28dffb9b02dd08a)) + + - **R-Car 3** + + - add a DRAM size setting for M3N ([f95d551](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f95d551217a287bd909aa3c82f4ade4986ad7244)) + - add new board revision for Salvator-XS/H3ULCB ([4379a3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4379a3e9744cf3b0844446335aca40357a889b9a)) + - add optional support for gzip-compressed BL33 ([ddf2ca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ddf2ca03979ea9fad305b1bc59beb6e27f0e1c02)) + - add process of SSCG setting for R-Car D3 ([14f0a08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/14f0a0817297905c03ddf2c4c6040482ef71d744)) + - add process to back up X6 and X7 register's value ([7d58aed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d58aed3b05fa8c677a7c823c1ca5017a462a3d3)) + - add SYSCEXTMASK bit set/clear in scu_power_up ([63a7a34](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/63a7a34706eedba4d13ce6fc661a634801cf8909)) + - apply ERRATA_A53_1530924 and ERRATA_A57_1319537 ([2892fed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2892fedaf27d8bbc68780a4a2c506c768e81b9f1)) + - change the memory map for OP-TEE ([a4d821a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4d821a5a625d941f95ec39fb51ac4fc07c46c5c)) + - emit RPC status to DT fragment if RPC unlocked ([12c75c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12c75c8886a0ee69d7e279a48cbeb8d1602826b3)) + - keep RWDT enabled ([8991086](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/899108601a0c3b08ead5e686d92ea0794700ff35)) + - modify LifeC register setting for R-Car D3 ([5460f82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5460f82806752e419fdd6862e8ca9c5fefbee3f2)) + - modify operation register from SYSCISR to SYSCISCR ([d10f876](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d10f87674ecee54cffe1ab554cc05733fd16c7f0)) + - modify SWDT counter setting for R-Car D3 ([053c134](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/053c134683cf74fbf4efad311815b806821f1436)) + - remove access to RMSTPCRn registers in R-Car D3 ([71f2239](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71f2239f53cd3137ad6abdaf0334dc53f2f21cb1)) + - update DDR setting for R-Car D3 ([042d710](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/042d710d1d917357c5142b340c79978264d3afb1)) + - update IPL and Secure Monitor Rev.3.0.0 ([c5f5bb1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c5f5bb17abfcf6c0eeb3e6c3d70499de0bd6abc0)) + - use PRR cut to determine DRAM size on M3 ([42ffd27](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42ffd279dd1a686b19e2f1b69d2e35413d5efeba)) + + - **ST** + + - add a new DDR firewall management ([4584e01](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4584e01dc643665038004f6c8a4f8bd64e14dacb)) + - add a USB DFU stack ([efbd65f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/efbd65fa7b5cf70f20d6b18152741ccdf8a65bb6)) + - add helper to save boot interface ([7e87ba2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e87ba2598a07facdeb73237dcb350a261ac17b6)) + - add STM32CubeProgrammer support on USB ([afad521](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/afad5214a79259f56bc2003b00859abfe8a18d4d)) + - add STM32MP_EMMC_BOOT option ([214c8a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/214c8a8d08b2b3c24f12cbc69f497f44851ca524)) + - create new helper for DT access ([ea97bbf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ea97bbf6a001b270fd0a25b4b0d0c382e277f3f8)) + - implement platform functions for SMCCC_ARCH_SOC_ID ([3d20178](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3d201787e8246022b1f193283c12e7cb4bfc83ff)) + - improve FIP image loading from MMC ([18b415b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/18b415be9d631b3e0c3a3caacc5f02edb9413f6b)) + - manage io_policies with FCONF ([d5a84ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d5a84eeaac2c8ce14d3f2662dc9523b4abf41516)) + - use FCONF to configure platform ([29332bc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/29332bcd680ce7e5f864813d9a900360f5e35d41)) + - use FIP to load images ([1d204ee](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1d204ee4ab12893fceb12097bd4f0a074be253b2)) + + - **ST32MP1** + + - add STM32MP_USB_PROGRAMMER target ([fa92fef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa92fef0a024cdb537fe56c84a0156cc48c1ac2d)) + - add USB DFU support for STM32MP1 ([942f6be](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/942f6be211d4816ad2568d30d807b8fd53d7f981)) + + - **Xilinx** + + - **Versal** + + - add support for SLS mitigation ([302b4df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/302b4dfb8fb0041959b8593a098ccae6c61e3238)) + + - **ZynqMP** + + - add support for runtime feature config ([578f468](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/578f468ac058bbb60b08f78e2aa2c20cdc601620)) + - sync IOCTL IDs ([38c0b25](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/38c0b2521a0ea0951f4e1ee678ccdbce5fc07a98)) + - add SDEI support ([4143268](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4143268a5ca8f91f1014e0d83edf766946ffff76)) + - add support for XCK26 silicon ([7a30e08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7a30e08b70e7fbb745554d500182bb6e258c5ab8)) + - extend DT description by TF-A ([0a8143d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0a8143dd636d4234dd2e79d32cb49dc80675c68f)) + +- **Bootloader Images** + + - import BL_NOBITS_{BASE,END} when defined ([9aedca0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9aedca021d917c7435aa2a0405972aa9d44493a2)) + +- **Services** + + - **FF-A** + + - adding notifications SMC IDs ([fc3f480](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fc3f480023e3a52460add25f18dd550dde44d9ff)) + - change manifest messaging method ([bb320db](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb320dbc4751f7ea0c37ffba07d14628e58081d0)) + - feature retrieval through FFA_FEATURES call ([96b71eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96b71eb9597efbf4857216cac1caeefc9e8bbf3e)) + - update FF-A version to v1.1 ([e1c732d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1c732d46fa91231b39209621ead1e5a5fb2c497)) + - add Ivy partition to tb fw config ([1bc02c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1bc02c2e0f63b6a7863e10cf6189292d42e693db)) + - add support for FFA_SPM_ID_GET ([70c121a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/70c121a258e43dc2462ed528b44d92594ffb27b3)) + - route secure interrupts to SPMC ([8cb99c3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8cb99c3fc3539bb9926e73a1c33fd72f424fc453)) + +- **Libraries** + + - **CPU Support** + + - add support for Hayes CPU ([7bd8dfb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7bd8dfb85a8bf5c22d6a39f4538b89cc748090d1)) + - add support for Hunter CPU ([fb9e5f7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb9e5f7bb76e9764b3ecd7973668c851015fa1b4)) + - workaround for Cortex A78 AE erratum 1941500 ([47d6f5f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47d6f5ff16d1f2ad009d630a381054b10fa0a06f)) + - workaround for Cortex A78 AE erratum 1951502 ([8913047](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8913047a52e646877812617a2d98cff99494487b)) + + - **MPMM** + + - add support for MPMM ([6812078](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68120783d6d6f99c605e9f746ee0e91e2908feb1)) + + - **OP-TEE** + + - introduce optee_header_is_valid() ([b84a850](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b84a850864c05fef587fcbb301f955428966de64)) + + - **PSCI** + + - require validate_power_state to expose CPU_SUSPEND ([a1d5ac6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1d5ac6a5aa5d9d18a481de20d272f64a71391f7)) + + - **SMCCC** + + - add bit definition for SMCCC_ARCH_SOC_ID ([96b0596](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/96b0596ea25e1f03b862a5bfaa92add6c3e51a33)) + +- **Drivers** + + - **FWU** + + - add FWU metadata header and build options ([5357f83](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5357f83d4ee89fb831d7e4f6149ae2f652e1b9af)) + - add FWU driver ([0ec3ac6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0ec3ac60d86b75d132e7a63fc09ea47e67f90bbd)) + - avoid booting with an alternate boot source ([4b48f7b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4b48f7b56577a78cdc9a2b47280cb62cbae0f7c3)) + - avoid NV counter upgrade in trial run state ([c0bfc88](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0bfc88f8e8e03974834cbcacbbfbd5f202a2857)) + - initialize FWU driver in BL2 ([396b339](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/396b339dc20b97ddd75146e03467a255e28f31b9)) + - introduce FWU platform-specific functions declarations ([efb2ced](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/efb2ced256dacbab71ca11cbc87f70f413ca6729)) + + - **I/O** + + - **MTD** + + - offset management for FIP usage ([9a9ea82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a9ea82948fd2f1459b6351cb0641f3f77b4e6de)) + + - **Measured Boot** + + - add documentation to build and run PoC ([a125c55](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a125c556230501ee0f5ec9f8b0b721625d484a41)) + - move init and teardown functions to platform layer ([47bf3ac](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/47bf3ac31ec84d4b221fdef760c04b5f4416cba4)) + - image hash measurement and recording in BL1 ([48ba034](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/48ba0345f7b42880ec4442d7e90e3e1af95feadd)) + - update tb_fw_config with event log properties ([e742bcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e742bcdae0d28dc14a2aa0b4ca30f50420bb5ebe)) + + - **MMC** + + - boot partition read support ([5014b52](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5014b52dec0c2527ca85c0fbe9c9281a24cc7b10)) + + - **MTD** + + - **NAND** + + - count bad blocks before a given offset ([bc3eebb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc3eebb25d5ee340e56047d0e46b81d5af85ff17)) + + - **SCMI** + + - add power domain protocol ([7e4833c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7e4833cdde8235d228f1f1c40f52b989ad5aa98a)) + + - **Arm** + + - **Ethos-N** + + - multi-device support ([1c65989](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c65989e70c9734defc666e824628620b2060b92)) + + - **GIC** + + - **GICv3** + + - detect GICv4 feature at runtime ([858f40e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/858f40e379684fefc8b52c7b9e60576bc3794a69)) + - introduce GIC component identification ([73a643e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/73a643eed9d88910a09ca666bc7ab7f5e532324e)) + - multichip: detect GIC-700 at runtime ([feb7081](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/feb7081863f454b9e465efc074ca669f7a4c783d)) + + - **GIC-600AE** + + - introduce support for Fault Management Unit ([2c248ad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c248ade2e958eed33127b4ea767fbb7499f31a7)) + + - **TZC** + + - **TZC-400** + + - update filters by region ([ce7ef9d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ce7ef9d146ce5ca6b9be5ef049377b3817d53d10)) + + - **MediaTek** + + - **APU** + + - add mt8192 APU device apc driver ([f46e1f1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f46e1f18539d6d992c82ae605c2cd2a1d0757fa4)) + - add mt8192 APU iommap regions ([2671f31](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2671f3187249d641c55929c812d6691aeeff502a)) + - add mt8192 APU SiP call support ([ca4c0c2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ca4c0c2e78eb19d442de4608d9096a755b540a37)) + - setup mt8192 APU_S_S_4 and APU_S_S_5 permission ([77b6801](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77b6801966d203e09ca118fad42543e934d73e6f)) + + - **EMI MPU** + + - add MPU support for DSP ([6c4973b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c4973b0a9a75aa83233b696c97d573426eebd98)) + + - **NXP** + + - **DCFG** + + - define RSTCR_RESET_REQ ([6c5d140](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6c5d140ed99cfec47b239acc242c0f3db1e3bf7c)) + + - **FLEXSPI** + + - add MT35XU02G flash info ([a4f5015](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4f5015a0080134251e9272719f5dad1ce2aa842)) + + - **Renesas** + + - **R-Car3** + + - add extra offset if booting B-side ([993d809](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/993d809cc115ce23dd2df1df19dc8bb548cc19cd)) + - add function to judge a DDR rank ([726050b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/726050b8e2d2ee2234e103e2df55f9c7f262c851)) + + - **ST** + + - manage boot part in io_mmc ([f3d2750](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f3d2750aa2293c0279bc447a85771827ca8b74c1)) + + - **USB** + + - add device driver for STM32MP1 ([9a138eb](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9a138eb5f29f6747e181a1b3b4199ad57721a3e0)) + + - **USB** + + - add a USB device stack ([859bfd8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/859bfd8d42341c6dea2b193db79dc4828e074ad7)) + +- **Miscellaneous** + + - **Debug** + + - add new macro ERROR_NL() to print just a newline ([fd1360a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fd1360a339e84ccd49f8a2d8a42e4c131a681b3c)) + + - **CRC32** + + - **Hardware CRC32** + + - add support for HW computed CRC ([a1cedad](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a1cedadf73863ff103fecd64fa188334e1541337)) + + - **Software CRC32** + + - add software CRC32 support ([f216937](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f21693704a7bac275e12b44ae30fd210bc317175)) + + - **DT Bindings** + + - add STM32MP1 TZC400 bindings ([43de546](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/43de546b909947ab44f104aaee02b98fba70f44c)) + + - **FDT Wrappers** + + - add CPU enumeration utility function ([2d9ea36](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2d9ea360350303e37a8dd39f3599ac88aaef0ff9)) + + - **FDTs** + + - add for_each_compatible_node macro ([ff76614](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ff766148b52bfecf09728a83fc3becc7941d943c)) + - introduce wrapper function to read DT UUIDs ([d13dbb6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d13dbb6f1d5e28737a3319af035a6cb991bc6f8f)) + - add firewall regions into STM32MP1 DT ([86b43c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86b43c58a4105c8cef13d860dd73fa9bd560526a)) + - add IO policies for STM32MP1 ([21e002f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21e002fb777fad9d02a94dc961f077fb444517fa)) + - add STM32MP1 fw-config DT files ([d9e0586](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d9e0586b619b331eb2db75911ca82f927e20bd1c)) + + - **STM32MP1** + + - align DT with latest kernel ([e8a953a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e8a953a9b85806f7324c8c7245435d5b9226c279)) + - delete nodes for non-used boot devices ([4357db5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4357db5b17ce6ba7357dd99276f34ab497ce60ef)) + + - **NXP** + + - **OCRAM** + + - add driver for OCRAM initialization ([10b1e13](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10b1e13bd200849ff134dd8d2fde341a8526f563)) + + - **PSCI** + + - define CPUECTLR_TIMER_2TICKS ([3a2cc2e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3a2cc2e262890cffee1fc46835e85be6055189e8)) + +- **Dependencies** + + - **libfdt** + + - also allow changing base address ([4d585fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4d585fe52feb231d5e73ec50a505122d5e9bf450)) + +### Resolved Issues + +- **Architecture** + +- **Platforms** + + - print newline before fatal abort error message ([a5fea81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5fea8105887d0dd15edf94aebd591b1b6b5ef05)) + + - **Allwinner** + + - delay after enabling CPU power ([86a7429](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/86a7429e477786dad6fab002538aef825f4ca35a)) + + - **Arm** + + - correct UUID strings in FVP DT ([748bdd1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/748bdd19aa27c15438d829bdba42fe4062a265a1)) + - fix a VERBOSE trace ([5869ebd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5869ebd0e87f1de987e51994103440fa8c77b26f)) + - remove unused memory node ([be42c4b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/be42c4b4bf3c44f2970b7a1658c46b8d5863cad1)) + + - **FPGA** + + - allow build after MAKE_* changes ([9d38a3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9d38a3e698331e3c8192cc3e0cc8584e6ed987d9)) + - avoid re-linking from executable ELF file ([a67ac76](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a67ac7648cd814ed8f8d4ece1b265c6d48c6dc81)) + - Change PL011 UART IRQ ([195381a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/195381a91313bc0bce2cfa087f3c55136a9e8496)) + - limit BL31 memory usage ([d457230](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d4572303ed45faceffed859955b0e71724fddfd2)) + - reserve BL31 memory ([13e16fe](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/13e16fee86451e2f871c2aac757b32299fe5ead6)) + - streamline generated axf file ([9177e4f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9177e4fd9356b0f249be8b6fe14f222e10f1e6cd)) + - enable AMU extension ([d810e30](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d810e30dd6b47e0725dccbcb42ca0a0c5215ee34)) + - increase initrd size ([c3ce73b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3ce73be0bfe31fa28805fe92b3e727232ffd37a)) + + - **FVP** + + - fix fvp_cpu_standby() function ([3202ce8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3202ce8bbb4af8580736d2a1634ad45c3f89d931)) + - spmc optee manifest remove SMC allowlist ([183725b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/183725b39d75e362a32b3c5d0be110c255c56bdd)) + - allow changing the kernel DTB load address ([672d669](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/672d669d6c72f92c6b81464d1d421e392bc1aa3e)) + - bump BL2 stack size ([d22f1d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d22f1d358731f0f55f2f392fa587f0fa8d315aa5)) + - provide boot files via semihosting ([749d0fa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/749d0fa80d1c7ca30b4092a381a06deeeaf1747f)) + - OP-TEE SP manifest per latest SPMC changes ([b7bc51a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b7bc51a7a747bf40d219b2041e5b3ce56737a71b)) + + - **FVP-R** + + - fix compilation error in release mode ([7d96e79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7d96e79a1a2efdf85f1ed46cdd5c577b58054f53)) + + - **Morello** + + - initialise CNTFRQ in Non Secure CNTBaseN ([7f2d23d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f2d23d9d790df90021de6c5165ef10fe5cc5590)) + + - **TC** + + - enable AMU extension ([b5863ca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b5863cab9adb3fed0c1e4dfb92cf906794e7bdb4)) + - change UUID to string format ([1c19536](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1c1953653c20b4a8c61a7deb3fc493d496d8c478)) + - remove "arm,psci" from psci node ([814646b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/814646b4cb792ab14df04e28360fefd168399b3c)) + - remove ffa and optee device tree node ([f1b44a9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f1b44a9050fbc12e8c260107bfff2930476df062)) + - set cactus-tertiary vcpu count to 1 ([05f667f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/05f667f0c670ba9682050714561309f00210c282)) + + - **SGI** + + - avoid redefinition of 'efi_guid' structure ([f34322c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f34322c1cea1e355aeb4133df6aa601d719be5a3)) + + - **Marvell** + + - Check the required libraries before building doimage ([dd47809](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dd47809e9ea75188060bf8b294efa8578d255c63)) + + - **Armada** + + - select correct pcie reference clock source ([371648e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/371648e1c76b5230bf8e153629064c02086365c9)) + - fix MSS loader for A8K family ([dceac43](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dceac436f620e60cd0149194377871b225216079)) + + - **A3K** + + - disable HANDLE_EA_EL3_FIRST by default ([3017e93](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3017e932768c7357a1a41493c58323419e9a1ec9)) + - enable workaround for erratum 1530924 ([975563d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/975563dbfc012b6e8a7765dd8e48220e1bc53dec)) + - Fix building uart-images.tgz.bin archive ([d3f8db0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d3f8db07b618e79c05805a1598e5e834e42fea98)) + - Fix check for external dependences ([2baf503](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2baf50385ba2b460afef4a7919b13b3a350fd03a)) + - fix printing info messages on output ([9f6d154](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9f6d15408340af07ed3c2500202b147189eaa7ef)) + - update information about PCIe abort hack ([068fe91](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/068fe919613197bf221c00fb84a1d94c66a7a8ca)) + - Remove encryption password ([076374c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/076374c9b97d47b10ba5c6034817866c08d66ed4)) + + - **A8K** + + - Add missing build dependency for BLE target ([04738e6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/04738e69917f8e8790bf4cf83ceb05f85e1f45bb)) + - Correctly set include directories for individual targets ([559ab2d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/559ab2df4a35cd82b2a67a0bebeb3028544a6766)) + - Require that MV_DDR_PATH is correctly set ([528dafc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/528dafc367c4f49d4904c4335422502dacf469bf)) + - fix number of CPU power switches. ([5cf6faf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5cf6fafe223da89c60e2323c242ea188b17e98c3)) + + - **MediaTek** + + - **MT8183** + + - fix out-of-bound access ([420c26b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/420c26b33a29c8328a1806ccb2f5a5885041fdfc)) + + - **MT8195** + + - use correct print format for uint64_t ([964ee4e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/964ee4e6be70ef638d6c875a761ab5ca359d84fe)) + - fix error setting for SPM ([1f81ccc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1f81cccedd40cb397813b0fa826ea1d793b02089)) + - extend MMU region size ([9ff8b8c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ff8b8ca9393e31e790eb2c8e7ea5c5f41f45198)) + - fix coverity fail ([85e4d14](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/85e4d14df157b5641421ea2b844c146ddc230152)) + + - **NXP** + + - **i.MX** + + - do not keep mmc_device_info in stack ([99d37c8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99d37c8cb8196a7296311fb4f97f80f086021c74)) + + - **i.MX 8M** + + - **i.MX 8M Mini** + + - fix FTBFS on SPD=opteed ([10bfc77](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/10bfc77e7b3afce17185114ac66361a0914f7784)) + + - **Layerscape** + + - **LX2** + + - **LS1028A** + + - define endianness of scfg and gpio ([2475f63](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2475f63bdec6c24c13f7d6ec7f70275b1bde5c15)) + - fix compile error when enable fuse provision ([a0da9c4](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a0da9c4bd296ec1a47683a1ee05f5d1ed71828c7)) + + - **QEMU** + + - (NS_DRAM0_BASE + NS_DRAM0_SIZE) ADDR overflow 32bit ([325716c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/325716c97b7835b8d249f12c1461556bab8c53a0)) + - reboot/shutdown with low to high gpio ([bd2ad12](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bd2ad12ef10f558a5b15f5768b66e7b2606c6498)) + + - **QTI** + + - **SC1780** + + - qti smc addition ([cc35a37](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cc35a3771d28a96906f8d0f393ff664924a2d4dc)) + + - **Raspberry Pi** + + - **Raspberry Pi 4** + + - drop /memreserve/ region ([5d2793a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5d2793a61aded9602af86e90a571f64ff07f93b3)) + + - **Renesas** + + - **R-Car** + + - change process that copy code to system ram ([49593cc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49593cc1ce0d0471aeef7ca24a5415da2dd55bea)) + - fix cache maintenance process of reading cert header ([c77ab18](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c77ab18ec7c8e0f3d953177b835e004a9b53515f)) + - fix to load image when option BL2_DCACHE_ENABLE is enabled ([d2ece8d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d2ece8dba2f31091b1fa6c302d4255495bb15705)) + + - **R-Car 3** + + - fix disabling MFIS write protection for R-Car D3 ([a8c0c3e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a8c0c3e9d0df2215ed3b9ef66f4596787d957566)) + - fix eMMC boot support for R-Car D3 ([77ab366](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77ab3661e55c39694c7ee81de2d1615775711b64)) + - fix source file to make about GICv2 ([fb3406b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb3406b6b573cb0b35138ca3c89c5641d3d7b790)) + - fix version judgment for R-Car D3 ([c3d192b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3d192b8e52823dcbc32e21e47c30693d38bb49f)) + - generate two memory nodes for larger than 2 GiB channel 0 ([21924f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21924f2466b9b5e1243c142932e6f498da5633e9)) + + - **Rockchip** + + - **RK3399** + + - correct LPDDR4 resume sequence ([2c4b0c0](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2c4b0c05c6546e24eb7209ffb3bb465d4feed164)) + - fix dram section placement ([f943b7c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f943b7c8e292e3aad2fcbdd0a37505f62b3b4c87)) + + - **Socionext** + + - **Synquacer** + + - update scmi power domain off handling ([f7f5d2c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7f5d2c4cd209c2d21244da4fa442050eb4531ab)) + + - **ST** + + - add STM32IMAGE_SRC ([f223505](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f22350583c2e26ea291eae3dc54db867fdf0d9af)) + - add UART reset in crash console init ([b38e2ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b38e2ed29ef791dad0cb61fed81b74d612f58b01)) + - apply security at the end of BL2 ([99080bd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/99080bd1273331007f0b2d6f64fed51ac6861bcd)) + - correct BSEC error code management ([72c7884](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/72c7884092684af4cc3c49e08f913b3ffed783ba)) + - correct IO compensation disabling ([c2d18ca](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c2d18ca80f4bd32f58ba07f53d9bb2586df18fc0)) + - correct signedness comparison issue ([5657dec](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5657decc7ffa1376c0a97b6d14ea1428877f5af4)) + - improve DDR get size function ([91ffc1d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/91ffc1deffa2c1c64efe4dfaf27b78f2621a8b0b)) + - only check header major when booting ([8ce8918](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8ce89187459ec77dd9ffdffba3a2b77838d51b6d)) + - panic if boot interface is wrong ([71693a6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/71693a66341e7d9d683ef32981243cb4c4439351)) + - remove double space ([306dcd6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/306dcd6b0d1981b75e103c560a4034bdaa6862d5)) + + - **ST32MP1** + + - add bl prefix for internal linker script ([7684ddd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7684dddcfb14c45bad33b091410a0bf14a3a9830)) + + - **Xilinx** + + - **Versal** + + - correct IPI buffer offset ([e1e5b13](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e1e5b1339b9f73f7f1893d8a6d4dfe4b19ba0ad1)) + - use sync method for blocking calls ([fa58171](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fa58171534976f94b93a44184afd050d8225e404)) + + - **ZynqMP** + + - use sync method for blocking calls ([c063c5a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c063c5a4f92d5787536e595ca4906b458b0f26cb)) + +- **Services** + + - drop warning on unimplemented calls ([67fad51](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/67fad514ee974dcf0252fa0e9219eb3c580eb714)) + + - **RME** + + - fixes a shift by 64 bits bug in the RME GPT library ([322b344](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/322b344e30cb87b9293060d5946b3c17fe3b9133)) + + - **SPM** + + - do not compile if SVE/SME is enabled ([4333f95](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4333f95bedb5f2b53dcb62e0e9c563794ec33c07)) + - error macro to use correct print format ([0c23e6f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0c23e6f44d41593b6e7f97594c12b5791bd75189)) + - revert workaround hafnium as hypervisor ([3221fce](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3221fce842c0b5aea984bb8dbc1393082bd88a58)) + - fixing coverity issue for SPM Core. ([f7fb0bf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/f7fb0bf77f3434bfb67411cad65e704fdef27f76)) + +- **Libraries** + + - **LIBC** + + - use long for 64-bit types on aarch64 ([4ce3e99](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4ce3e99a336b74611349595ea7fd5ed0277c3eeb)) + + - **CPU Support** + + - correct Demeter CPU name ([4cb576a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4cb576a0c5bd2e7669606996a9f79602596df07c)) + - workaround for Cortex A78 erratum 2242635 ([1ea9190](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ea9190c6a4d2299c6dc19adc0bbe93d4f051eff)) + - workaround for Cortex-A710 erratum 2058056 ([744bdbf](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/744bdbf732ffd2abf84b2431624051e93bc29f7b)) + - workaround for Neoverse V1 erratum 2216392 ([4c8fe6b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4c8fe6b17fa994a630b2a30f8666df103f2e370d)) + - workaround for Neoverse-N2 erratum 2138953 ([ef8f0c5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef8f0c52ddf83e815a029319971682d7a26b6a6f)) + - workaround for Neoverse-N2 erratum 2138958 ([c948185](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c948185c973c13df36c62c4bcb50e22b14d6e06a)) + - workaround for Neoverse-N2 erratum 2242400 ([603806d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/603806d1376c4b18211fb1d4cc338153de026c32)) + - workaround for Neoverse-N2 erratum 2242415 ([5819e23](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5819e23bc47c860872141caf42bddddb1b8679a5)) + - workaround for Neoverse-N2 erratum 2280757 ([0d2d999](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0d2d99924e1be548e75c46cfd536f7503cf863e0)) + - rename Matterhorn, Matterhorn ELP, and Klein CPUs ([c6ac4df](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c6ac4df622befb5bb42ac136745094e1498c91d8)) + + - **EL3 Runtime** + + - correct CASSERT for pauth ([b4f8d44](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b4f8d44597faf641177134ee08db7c3fcef5aa14)) + - fix SVE and AMU extension enablement flags ([68ac5ed](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/68ac5ed0493b24e6a0a178171a47db75a31cc423)) + - random typos in tf-a code base ([2e61d68](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2e61d6871cc310e9404fe5cfa10b9828f1c869a7)) + - Remove save/restore of EL2 timer registers ([a7cf274](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a7cf2743f3eb487912302aafc748c81bbd1fc603)) + + - **OP-TEE** + + - correct signedness comparison ([21d2be8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/21d2be83a2eabb328071e857e538ced3c8351874)) + + - **GPT** + + - add necessary barriers and remove cache clean ([77612b9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77612b90acaffc82cea712f4a431c727bbb968ec)) + - use correct print format for uint64_t ([2461bd3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/2461bd3a89f7f2cdf4a7302536746733970cfe53)) + + - **Translation Tables** + + - remove always true check in assert ([74d720a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/74d720a026735263d2f290fd05370dad0d4c7219)) + +- **Drivers** + + - **Authentication** + + - avoid NV counter upgrade without certificate validation ([a2a5a94](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a2a5a9456969266dc68d5845f31e05be0c3ff2e3)) + + - **CryptoCell-713** + + - fix a build failure with CC-713 library ([e5fbee5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e5fbee5085c682ac3438e6f66c8bdaffb6076fa2)) + + - **MTD** + + - fix MISRA issues and logic improvement ([5130ad1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5130ad14d52a0196422fed8a7d08e25659890b15)) + - macronix quad enable bit issue ([c332740](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c3327408eb4b5852c0ed9d8933c35aaa6de34c21)) + + - **NAND** + + - **SPI NAND** + + - check correct manufacturer id ([4490b79](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4490b7963303fbe59b07a66c8498a803eb5c239c)) + - check that parameters have been set ([bc453ab](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bc453ab1b2fd4267d34f2b9587f73b8940ee1538)) + + - **SCMI** + + - entry: add weak functions ([b3c8fd5](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b3c8fd5d778144340d289ad4825123106aac4a96)) + - smt: fix build for aarch64 ([0e223c6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0e223c6a9e5a2d92cae00fdd16a02a3f8971b114)) + - mention "SCMI" in driver initialisation message ([e0baae7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/e0baae7316bfdf3e49e5e158f79eb80cd51fc700)) + - relax requirement for exact protocol version ([125868c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/125868c94150f52ff85cdb59aee623ab1f9f259d)) + + - **UFS** + + - add reset before DME_LINKSTARTUP ([905635d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/905635d5e74e3c7b7b2412a673009c8aaabb73e1)) + + - **Arm** + + - **GIC** + + - **GICv3** + + - add dsb in both disable and enable function of gicv3_cpuif ([5a5e0aa](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a5e0aac398989536dc4be790820af89da3d093a)) + + - **GIC-600AE** + + - fix timeout calculation ([7f322f2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7f322f228e76caa5480f827af0aa6751f00fc1c4)) + + - **TZC** + + - **TZC-400** + + - never disable filter 0 ([ef378d3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ef378d3ec1ef9d7c28baef32ed409688e962542b)) + + - **Marvell** + + - **COMPHY** + + - fix name of 3.125G SerDes mode ([a669983](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a669983c78828e3f4a4f14b9e5a6ee79dcfde20f)) + + - **Armada 3700** + + - configure phy selector also for PCIe ([0f3a122](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0f3a1221093256999af5f2a80e9b3d7231b9f5fb)) + - fix address overflow ([c074f70](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c074f70ce5d85e1735b589b323fac99d7eb988b5)) + - handle failures in power functions ([49b664e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49b664e75f43fda08dddef4f0510d346bdd25565)) + + - **CP110** + + - fix error code in pcie power on ([c0a909c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c0a909cdcce2d9a2ceefe672ad2fc1cae7e39ec4)) + + - **Armada** + + - **A3K** + + - **A3720** + + - fix configuring UART clock ([b9185c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b9185c75f7ec2b600ebe0d49281e216a2456b764)) + - fix UART clock rate value and divisor calculation ([66a7752](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/66a7752834382595d26214783ae4698fd1f00bd6)) + - fix UART parent clock rate determination ([5a91c43](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5a91c439cbeb1f64b8b9830de91efad5113d3c89)) + + - **MediaTek** + + - **PMIC Wrapper** + + - update idle flow ([9ed4e6f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/9ed4e6fb669b8fcafc4e8acfa6a36db305d27ac8)) + + - **MT8192** + + - **SPM** + + - add missing bit define for debug purpose ([310c3a2](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/310c3a26e17d99aafc73b3504d0b6dfbdb97fd4c)) + + - **NXP** + + - **FLEXSPI** + + - fix warm boot wait time for MT35XU512A ([1ff7e46](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/1ff7e46b092b74891bc2dc7263e4dfae947b2223)) + + - **SCFG** + + - fix endianness checking ([fb90cfd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/fb90cfd4eee504f1d16aa143728af427dc6e0ed8)) + + - **SFP** + + - fix compile warning ([3239a17](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3239a17561c124df7095391c0d64e86910660cdc)) + + - **Renesas** + + - **R-Car3** + + - console: fix a return value of console_rcar_init ([bb273e3](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bb273e3be1c4f1cddeac9ceaac95fb56e41e6b98)) + - ddr: update DDR setting for H3, M3, M3N ([ec767c1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ec767c1b99675fbb50ef1b2fdb2d38e881e4789d)) + - emmc: remove CPG_CPGWPR redefinition ([36d5645](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/36d5645aec947ab00b925b21141e59e58e1efd8c)) + - fix CPG registers redefinition ([0dae56b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0dae56bb2f0aa1f89ec98ebe3931fb19751a5c72)) + - i2c_dvfs: fix I2C operation ([b757d3a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b757d3a1d901bee9b7ad430702575adba04889ba)) + + - **ST** + + - **Clock** + + - use correct return value ([8f97c4f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8f97c4fab1769b3f7f37a2a7a01ade36e5c94eaa)) + - correctly manage RTC clock source ([1550909](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/15509093f0ba9a10f97c6f92bc3bb9fcf79a48ce)) + - fix MCU/AXI parent clock ([b8fe48b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/b8fe48b6f2b07fce49363cb3c0f8dac9e286439b)) + - fix MPU clock rate ([602ae2f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/602ae2f23c2bc9d79a9ab2b7c5dde1932fffc984)) + - fix RTC clock rating ([cbd2e8a](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cbd2e8a6afdd05c4b404d7998134a3f60cc15518)) + - keep RTC clock always on ([5b111c7](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/5b111c74795ea5e9c8a12d0e6b18d77e431311ed)) + - keep RTCAPB clock always on ([373f06b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/373f06be4ee1114369b96763481b58885623aea4)) + - set other clocks as always on ([bf39318](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/bf39318d93c270ff72bda4b46e4771aba7aea313)) + + - **I/O** + + - **STM32 Image** + + - invalidate cache on local buf ([a5bcf82](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a5bcf82402ff415326b4dba42aae95c499821e94)) + - uninitialized variable warning ([c1d732d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c1d732d0db2463998036c678619007da79a25b3f)) + + - **ST PMIC** + + - initialize i2c_state ([4282284](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/42822844bfed2e9ffaeae850cc60f5c3d4d9d654)) + - missing error check ([a4bcfe9](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a4bcfe94e73db89ce2ebbb23c8e33e51eea5026a)) + + - **STPMIC1** + + - fix power switches activation ([0161991](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0161991184e5feacacc679bdb9c92681b85235eb)) + - update error cases return ([ed6a852](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/ed6a85234653c5ee2520389b769ff47e321df8a4)) + + - **UART** + + - **STM32 Console** + + - do not skip init for crash console ([49c7f0c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49c7f0cef4cc864185828750f1f61f3f33f284f7)) + + - **USB** + + - add a optional ops get_other_speed_config_desc ([216c122](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/216c1223c2c65bd1c119a28b9406f70a9ee7b063)) + - fix Null pointer dereferences in usb_core_set_config ([0cb9870](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0cb9870ddfa1b2fec50debe6d6333cbcb3df1e7e)) + - remove deadcode when USBD_EP_NB = 1 ([7ca4928](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7ca49284be083b03ae11aa348b40358876ee5d4b)) + - remove unnecessary cast ([025f5ef](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/025f5ef201a39ba7285f368139e690bbd7a44653)) + +- **Miscellaneous** + + - use correct printf format for uint64_t ([4ef449c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4ef449c15a4055d92632cb7e72267f525a7e2fca)) + + - **DT Bindings** + + - fix static checks ([0861fcd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/0861fcdd3e3f2625e133de3dae9c548de7c1ee48)) + + - **FDTs** + + - avoid output on missing DT property ([49e789e](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/49e789e353efaf97f84eca016c6a1b8a2b3e3d98)) + - fix OOB write in uuid parsing function ([d0d6424](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0d642450f1f3a0f43e0e156ef57a0c460dd48cf)) + + - **Morello** + + - fix scmi clock specifier to cluster mappings ([387a906](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/387a9065a271ecde0e47dc5a9f9d037637502beb)) + + - **STM32MP1** + + - correct copyright dates ([8d26029](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d26029168fe70a86de524ed68c56e8666823714)) + - set ETH clock on PLL4P on ST boards ([3e881a8](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/3e881a8834a955f1e552300bdbf1dafd02ea8f1c)) + - update PLL nodes for ED1/EV1 boards ([cdbbb9f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/cdbbb9f7ecd4687fa52e1c655b631377c24862b9)) + - use 'kHz' as kilohertz abbreviation ([4955d08](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/4955d08de7aa664387d2e5f690e78b85ac23a402)) + + - **PIE** + + - invalidate data cache in the entire image range if PIE is enabled ([596d20d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/596d20d9e4d50c02b5a0cce8cad2a1c205cd687a)) + + - **Security** + + - Set MDCR_EL3.MCCD bit ([12f6c06](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/12f6c0649732a35a7ed45ba350a963f09a5710ca)) + + - **SDEI** + + - fix assert while kdump issue ([d39db26](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d39db2695ba626b9c0ee38652fe160b4e84b15d9)) + - print event number in hex format ([6b94356](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6b94356b577744d425476a029c47bd35eb13c148)) + - set SPSR for SDEI based on TakeException ([37596fc](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/37596fcb43e34ed4bcf1bd3e86d8dec1011edab8)) + +- **Documentation** + + - fix TF-A v2.6 release date in the release information page ([c90fa47](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/c90fa47202b762fe8f54e9c0561e94d37907b6ad)) + - fix `FF-A` substitution ([a61940c](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/a61940ca739eb89be7c1bb2408a9178c2da5cb70)) + - fix typos in v2.5 release documentation ([481c7b6](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/481c7b6b9107a3f71ee750f89cacdd8f9c729838)) + - remove "experimental" tag for stable features ([700e768](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/700e7685dd4682a929645a79de39f503c9140b2d)) + + - **Contribution Guidelines** + + - fix formatting for code snippet ([d0bbe81](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/d0bbe8150eb35fe2bac1567751bf84a8f073dd39)) + +- **Build System** + + - use space in WARNINGS list ([34b508b](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/34b508be9f021831423a8a14f56dff547e24c743)) + + - **Git Hooks** + + - downgrade `package-lock.json` version ([7434b65](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/7434b65208175bdf3f44e0e62aaaeabc9c494ee3)) + +- **Tools** + + - **STM32 Image** + + - improve the tool ([8d0036d](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/8d0036d3d8c8ac1524539ea90382acafb1e524c0)) + + - **SPTOOL** + + - SP UUID little to big endian in TF-A build ([dcdbcdd](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/dcdbcddebdee8d4d2c6c8316f615b428758b22ac)) + + - **DOIMAGE** + + - Fix doimage syntax breaking secure mode build ([6d55ef1](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/6d55ef1a24dc92a3b737aaa02141f550caaace06)) + +- **Dependencies** + + - **checkpatch** + + - do not check merge commits ([77a0a7f](https://review.trustedfirmware.org/plugins/gitiles/TF-A/trusted-firmware-a/+/77a0a7f1d96b188849d1d8d8884b3c93857d3f69)) + ## 2.5.0 (2021-05-17) ### New Features -- cgit v1.2.3